練習
直接執行有setTimeout的Promise, 但因javascript是非同步執行, 不會等待後再執行結束的log
console.log(getTime()+'..start');
new Promise(resolve => {setTimeout(resolve, 1000); });
console.log(getTime()+'..end');
//結果: 沒有等待
/*
"7:15:28..start"
"7:15:28..end"
*/
修改成async IIFE, 以新增await運算子
(async () => {
console.log(getTime()+'..start');
await new Promise(resolve => {setTimeout(resolve, 1000); });
console.log(getTime()+'..end');
})();
//結果: first等待1秒鐘
/*
"7:16:59..start"
"7:17:00..end"
*/
目標-執行程式結束後, 再執行另一段-把函式當參數傳入
var start = function(callback) {
console.log('start '+getTime());
setTimeout(()=>{
if( typeof callback === 'function' ){
callback();
}
}, 1000);
}
var next = function() {
console.log('doNext '+getTime());
}
start(next);
//結果:
/*
"start 21:24:15"
"doNext 21:24:16"
*/
以上程式, 一層一層加疊, 造成callback hell, 會多層巢狀, 很難控制每種狀況及導出的結果
目標-執行程式結束後, 再執行另一段-用async, await控制
//調整start
var start = async() => {
console.log('start '+getTime());
await new Promise(resolve => {setTimeout(resolve, 1000); });
}
(async()=>{
await start()
.then(()=>next());
})();
目標-先執行一段程式, 並依程式結果, 決定接下來要執行哪段程式
var doNext = () => {
console.log('doNext '+getTime());
}
var check = async(condition) => {
console.log(`check ${condition} ${getTime()}..start`);
await new Promise((resolve, reject) => {
if (condition) {//依condition決定要走resolve或reject
setTimeout(function () {resolve();}, 3000);
} else {
reject(`failed, rejected.`)
}
});
}
/*寫法一: 先then再catch*/
/*
(async () => {
await check(false)
.then(()=>doNext())
.catch(response => {console.log(response); });
await check(true)
.then(()=>doNext())
.catch(response => {console.log(response); });
})();
*/
/*寫法二: then裡直接兩個anonymouse function, 第二個處理catch*/
/*
(async () => {
await check(false)
.then(
() => doNext(),
(response) => {console.log(response);}
);
await check(true)
.then(
()=>doNext(),
(response) => {console.log(response);}
);
})();
*/
/*寫法三: Promise chain*/
(async () => {
await check(false)
.then(
(response) => check(true),
(response) => {console.log(response);}
)
.then(
(response) => check(true),
(response) => {console.log(response);}
)
.then(
()=>doNext(),
);
})();
//結果
/*
"check false 22:36:36..start"
"failed, rejected."
"check true 22:36:36..start"
"doNext 22:36:39"
*/
以asp.net的async例子-做早餐做練習, 有倒咖啡, 煎蛋, 煎培根, 烤土司並塗上奶油及果醬, 倒果汁共5項工作
目標:一步接一步作業, 做完一項工作, 再開始另一項
var makeBreakfastSteply = async() => {
...
console.log(`Let's Making Breakfast!`);
await pourCoffee(2);
console.log(`coffee is ready`);
await fryBaconAsync(1);
await fryEggsAsync(4);
await makeToastWithButterAndJamAsync(2);
pourJuice();
...
}
//花費約18秒鐘
目標-先倒完咖啡, 再請家人幫忙, 煎蛋, 煎培根, 烤土司並塗上奶油及果醬三項工作同時開工, 待工作都完成, 再倒一杯果汁
var makeBreakfastAsync = async() => {
console.log(`Let's Making Breakfast!`);
await pourCoffee(2);
console.log(`coffee is ready`);
await Promise.all([fryBaconAsync(1), fryEggsAsync(4), makeToastWithButterAndJamAsync(2)])
.then(() => pourJuice())
.catch(response => {console.log(response); });
...
}
//花費約8秒鐘