備忘錄_20160105(定位)
修改
回首頁
程式 2020-05-21 04:52:04 1590007924 100
JavaScript Promise, async, await
JavaScript Promise, async, await
<script>
function waitForMe()
{
return new Promise
(
(成功, 失敗) =>
{
// 標的:成功、失敗、throw
// 任何時候,只要一遇到 「throw」,後面的程式就不會再執行。
// 若遇到「throw」之前,沒有呼叫過「成功」或「失敗」函數,
// 則跳到 catch
// 只要遇到第一個「成功」或「失敗」函數呼叫,
// 後頭不管還有多少個「成功」或「失敗」呼叫,一概不予理會。
// 但請注意,「成功」或「失敗」函數呼叫之後的程式碼,"還會"繼續執行喔!
// 因為上述兩條規則,在錯縱複雜的執行情形底下,
// 有可能最後執行到 then ,但其實是有錯誤發生的,而且看不到!!! (例如 condition=1)
// 或是有 throw 發生,但你可能只會看到「失敗」函數呼叫的結果!!! (例如 condition=2)
// 或是有「成功」函數+「失敗」函數+throw,但您只會看到成功訊息! (例如 condition=3)
var condition=3;
console.log("Promise created.(檢查點 A)");
if((condition & 1)==1)
{
console.log("Promise created.(檢查點 B)");
成功('成功函數的呼叫,僅第一個有用');
成功('成功函數的呼叫,第二個(含)之後都會被忽略');
}
if((condition & 2)==2)
{
console.log("Promise created.(檢查點 C)");
失敗('失敗函數的呼叫,僅第一個有用');
失敗('失敗函數的呼叫,第二個(含)之後都會被忽略');
}
console.log("Promise created.(檢查點 D)");
throw 'throw 錯誤!throw 錯誤!';
console.log("Promise created.(檢查點 E)");
}
)
.then( (參數)=>{ console.log("最後結果 success:"+參數); } )
.catch( (參數)=>{ console.log("最後結果 failure:"+參數); } );
}
async function main()
{
console.log("main() begin...");
await waitForMe();
console.log("main() end...");
}
console.log("before main() ......");
main();
console.log("after main() ...... 照樣非同步執行喔!");
// 04:21:58.841 before main() ...... a.htm:60:9
// 04:21:58.842 main() begin... a.htm:55:11
// 04:21:58.843 Promise created.(檢查點 A) a.htm:26:15
// 04:21:58.844 Promise created.(檢查點 B) a.htm:30:17
// 04:21:58.844 Promise created.(檢查點 C) a.htm:37:17
// 04:21:58.845 Promise created.(檢查點 D) a.htm:42:15
// 04:21:58.845 after main() ...... 照樣非同步執行喔! a.htm:62:9
// 04:21:58.846 最後結果 success:成功函數的呼叫,僅第一個有用 a.htm:48:27
// 04:21:58.846 main() end... a.htm:57:11
</script>
<script>
function delay(interval)
{
// usage:
//
// async function main()
// {
// ......
// await delay(3000);
// ......
// }
//
// main();
//
return new Promise((empty)=>{ setTimeout(empty, interval); });
}
function complexDelay(taskName, interval)
{
return new Promise
(
(成功)=>
{
console.log(taskName+" 工作開始,需時 "+(interval/1000)+" 秒");
window.setTimeout(()=>{ 成功(taskName); }, interval);
}
)
.then( (value)=>{ console.log("("+value+"-"+interval+") - 完成!"); } );
}
async function task(taskName, interval1, interval2)
{
console.log(taskName+" 工作開始");
await complexDelay(taskName+"第一階段", interval1);
await complexDelay(taskName+"第二階段", interval2);
console.log(taskName+" 工作結束");
}
async function main()
{
await task("晨間開會", 3000, 2000);
await task("撰寫程式", 1000, 4000);
}
console.log("before main() -- 非同步喔");
main();
console.log("after main() -- 非同步喔");
// 04:51:28.576 before main() -- 非同步喔 b.htm:47:9
// 04:51:28.577 晨間開會 工作開始 b.htm:35:11
// 04:51:28.577 晨間開會第一階段 工作開始,需時 3 秒 b.htm:26:15
// 04:51:28.578 after main() -- 非同步喔 b.htm:49:9
// 04:51:31.578 (晨間開會第一階段-3000) - 完成! b.htm:30:29
// 04:51:31.579 晨間開會第二階段 工作開始,需時 2 秒 b.htm:26:15
// 04:51:33.580 (晨間開會第二階段-2000) - 完成! b.htm:30:29
// 04:51:33.581 晨間開會 工作結束 b.htm:38:11
// 04:51:33.581 撰寫程式 工作開始 b.htm:35:11
// 04:51:33.582 撰寫程式第一階段 工作開始,需時 1 秒 b.htm:26:15
// 04:51:34.583 (撰寫程式第一階段-1000) - 完成! b.htm:30:29
// 04:51:34.584 撰寫程式第二階段 工作開始,需時 4 秒 b.htm:26:15
// 04:51:38.584 (撰寫程式第二階段-4000) - 完成! b.htm:30:29
// 04:51:38.585 撰寫程式 工作結束 b.htm:38:11
</script>
其他參考JavaScript 永遠是同步的,單一執行緒的。只是太多地方隱含 callback