天天看點

一份html+js檔案讓你輕松看懂promise對象與async+await

注意看注釋哦,可以把整個檔案複制去你的編輯器,運作然後嘗試一下!

樣式不重要,浏覽器F12看console.log()列印的值

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			html,
			body {
				width: 100%;
				height: 100%;
			}

			#btn,
			#btn2 {
				width: 100px;
				height: 100px;
				margin: 0 auto;
				display: block;
				margin-top: 25%;
				transform: translateY(-50%);
			}
		</style>
	</head>
	<body>
		<button id="btn">promise-resolve</button>
		<button id="btn2">promise-reject</button>
		<script type="text/javascript">
			//promise對象  可以通過在通過then()方法和catch()方法捕獲到兩個不同回調的值
			var btn = document.getElementById("btn");
			// resolve 用法
			btn.onclick = function() {
				function runAsync(num) {
					return new Promise(function(resolve, reject) {
						//做一些異步操作
						setTimeout(function() {
							console.log('執行完成', num);
							resolve(`随便什麼資料${num}`);
						}, 1000);
					});
				}
				//promise對象的鍊式調用
				runAsync(1).then(data => {
					console.log(data);
					return runAsync(2);
				}).then(function(data) {
					console.log(data);
					return runAsync(3);
				}).then(function(data) {
					console.log(data);
				})
			}

			// resolve 和 reject 用法  
			var btn2 = document.getElementById("btn2");
			btn2.onclick = function() {
				function getNumber() {
					var p = new Promise(function(resolve, reject) {
						//做一些異步操作
						setTimeout(function() {
							var num = Math.ceil(Math.random() * 10); //生成1-10的随機數
							if (num <= 5) {
							//  ----------------當if的條件滿足,則調用resolve去改變promise對象的狀态為已成功
								resolve(num);
							} else {
							  ----------------當if的條件 不 滿足,則調用reject去改變promise對象的狀态為已失敗
								reject('數字太大了');
							}
						}, 1000);
					});
					return p;
				}
				
				//promise對象建立的同時會立即執行,是以需要封裝進一個方法裡面,這樣我們通過調用這個方法   在合适的時機  執行
				// 調用上面封裝好的promise方法
				
				getNumber()
					.then(  //then裡兩個參數分别是成功和失敗的回調函數
						//第一個對應resolved
						function(data) {
							console.log('resolved');
							console.log(data);
						},
						//第二個對應rejected
						function(data) {
							console.log('rejected');
							console.log(data);
						}
					)
			}

			// ----------------async與awite---------------------
			
			//建立一個異步的方法 ----  timeout()
			async function timeout() {
				return 'hello world';
			}
			
			//async 函數傳回的是一個 promise 對象,如果要擷取到 promise 傳回值,我們應該用then 方法
			timeout().then(data => {
				console.log(data)
			});
			console.log('雖然在後面,但是我先執行');

			//-------------------------------------------------

			// 2s 之後傳回雙倍的值
			function doubleAfter2seconds(num) {
				return new Promise((resolve, reject) => {
					setTimeout(() => {
						resolve(2 * num)
					}, 2000);
				})
			}
			
			//async和await 二者必須是結合着使用
			//await 是個運算符,用于組成表達式,await 表達式的運算結果取決于它等的東西
			//await 後面也可以不是promise對象,那 await 表達式的運算結果就是它等到的東西
			
			async function testResult() {
				//等待doubleAfter2seconds函數傳回結果後執行
				//doubleAfter2seconds傳回的是一個promise對象,
				let first = await doubleAfter2seconds(30);
				// await 表示等一下,代碼就暫停到這裡,不再向下執行了,它等什麼呢?等後面的promise對象執行完畢,然後拿到promise resolve 的值并進行傳回,傳回值拿到之後,它繼續向下執行
				let second = await doubleAfter2seconds(50);
				let third = await doubleAfter2seconds(30);
				console.log(first + second + third);
			}
			testResult();
		</script>
	</body>
</html>