2 回答

TA貢獻(xiàn)1895條經(jīng)驗(yàn) 獲得超7個贊
我認(rèn)為 async 主要用于 api 調(diào)用(?)
有兩個與該詞相關(guān)的不同概念async
:
async/await
函數(shù)以同步方式接收 Promises 結(jié)果的語法糖真正的異步行為 XHR api 調(diào)用、延遲執(zhí)行、事件處理
async/await
function 不會自動使您的函數(shù)執(zhí)行異步。
const foo = async (i) => { console.log('foo running', i); return i == 0 ? 42 : await foo(i-1); };
console.log('foo before')
foo(5)
.then(x => console.log('foo', x))
console.log('foo after')
// foo before
// foo running 5
// foo running 4
// foo running 3
// foo running 2
// foo running 1
// foo running 0
// foo after
// foo 42
JavaScript 是單線程的,所有并發(fā)任務(wù)必須分成異步塊,以便其他任務(wù)有機(jī)會工作。
因此,您應(yīng)該將同步循環(huán)拆分為許多異步部分,以免被凍結(jié)。
例如(我減少參數(shù)以便沒有太多等待時間):
async function calcX() {
let x = 0;
function iteration(i) {
x += (i * 99999);
if (++i >= 10000) return Promise.resolve(x);
return new Promise((resolve) => {
setTimeout(() => iteration(i).then(resolve), 0);
// or requestAnimationFrame
});
}
return await iteration(1);
}
const start = Date.now();
calcX()
.then(x => console.log(x, Date.now() - start), err => console.error(err));
// 4999450005000 42465
如果將每次迭代都放入事件循環(huán)中,它可能會太慢。所以你可以通過批處理它們來優(yōu)化它(參見@Steve的答案)
或者使用 WebWorker 來完成繁重的同步任務(wù)

TA貢獻(xiàn)1810條經(jīng)驗(yàn) 獲得超5個贊
您可以通過檢查是否已經(jīng)過了設(shè)定的時間,然后稍后返回該函數(shù),將長時間運(yùn)行的同步函數(shù)轉(zhuǎn)換為異步函數(shù)(在此示例中通過 實(shí)現(xiàn))setTimeout:
var lastBreak = Date.now()
function takeABreak() {
return new Promise(resolve=>setTimeout(resolve));
}
async function maybeTakeABreak() {
if (Date.now() - 17 > lastBreak) {
lastBreak = Date.now();
await takeABreak();
}
}
async function myLongLoop() {
let x = 0;
for (let i = 1; i < 100000000000000; i++) {
await maybeTakeABreak();
x += (i * 99999);
if (!(i%1000000)) {
console.log(i);
// alternatively you could run `await takeABreak();` here
}
}
return x;
}
myLongLoop().then(x=>console.log(x));
添加回答
舉報(bào)