JavaScript是單線程並在相同的線程中運行UI。所有的JavaScript代碼都會阻止用戶界面。正如其他人所提到的,網絡工作者可以用來在其他線程中運行代碼,但是它們有侷限性。
異步函數和常規函數之間的區別是它們返回一個承諾。然後使用回調,可以推遲執行代碼,該代碼處理函數調用的結果,從而允許UI執行一些工作。下面的三個例子具有相同的效果:
async function foo() {
console.log("hi");
return 1;
}
foo().then(result => console.log(result))
console.log("lo");
function foo() {
console.log("hi");
return 1;
}
Promise.resolve(foo()).then(result => console.log(result))
console.log("lo");
function foo() {
console.log("hi");
return 1;
}
const result = foo();
setTimeout(() => console.log(result));
console.log("lo");
在所有這三種情況下,控制檯日誌HI,LO,1。1之前被印刷在UI可以處理用戶輸入或繪製更新。在前兩種情況中最後打印的原因是,承諾回調不會立即執行。
await
允許你這樣做,如果沒有回調:
async function foo() {
console.log("hi");
return 1;
}
async function bar() {
const result = await foo();
console.log(result);
}
bar();
console.log("lo");
這也將打印HI,LO,1很像一個承諾回調,await
後的代碼永遠不會立即執行。
代碼塊仍然會阻塞。如果沒有,你可以進行數據競賽。異步函數的思想是你可以暫停等待稍後執行異步代碼。所以你在等待異步完成時停下來,比如'setTimeout',一個XHR響應或事件一個點擊事件:https://jsfiddle.net/wgqyayhr/ *(Demo需要支持的瀏覽器)* –
'異步/ await'是**不是** ES7(ES2016)的一部分。這將成爲今年發佈的ES2017的一部分。 –