2 回答

TA貢獻1895條經驗 獲得超7個贊
我認為 async 主要用于 api 調用(?)
有兩個與該詞相關的不同概念async
:
async/await
函數以同步方式接收 Promises 結果的語法糖真正的異步行為 XHR api 調用、延遲執行、事件處理
async/await
function 不會自動使您的函數執行異步。
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 是單線程的,所有并發任務必須分成異步塊,以便其他任務有機會工作。
因此,您應該將同步循環拆分為許多異步部分,以免被凍結。
例如(我減少參數以便沒有太多等待時間):
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
如果將每次迭代都放入事件循環中,它可能會太慢。所以你可以通過批處理它們來優化它(參見@Steve的答案)
或者使用 WebWorker 來完成繁重的同步任務

TA貢獻1810條經驗 獲得超5個贊
您可以通過檢查是否已經過了設定的時間,然后稍后返回該函數,將長時間運行的同步函數轉換為異步函數(在此示例中通過 實現)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));
添加回答
舉報