如何使用异步替代 Promise.resolve().then()?

How to use async alternative for Promise.resolve().then()?

运行 片段并查看它们的持续时间,您会发现第一个片段在 billion loops done 之前执行 log('Synchronous 2')。它花费了 0 毫秒,但是第二个片段使用异步关键字块 log('Synchronous 2')直到循环完成。

const tick = Date.now();
const log = (v) => console.log(`${v} \n Elapsed: ${Date.now() - tick}ms`);

const notBlocked = () => {
    return Promise.resolve().then(() =>  {
        let i = 0;
        while(i < 1000000000) { i++; } //runs asynchronically
        return ' billion loops done';
    })
}

log(' Synchronous 1');
notBlocked().then(log);
log(' Synchronous 2');

日志('Synchronous 2')被屏蔽

const tick = Date.now();
const log = (v) => console.log(`${v} \n Elapsed: ${Date.now() - tick}ms`);

const notBlocked = async() => {
    let i = 0;
    while(i < 100000000) { i++; } //runs synchronically and blocks main thread
    return ' billion loops done';
}

log(' Synchronous 1');
notBlocked().then(log);
log(' Synchronous 2');

异步函数 运行 同步运行直到遇到等待,所以如果你的目标是使用异步函数来延迟一些代码作为微任务,你需要在其中放置一个等待,即使它在等待一些无用的东西。

const tick = Date.now();
const log = (v) => console.log(`${v} \n Elapsed: ${Date.now() - tick}ms`);

const notBlocked = async () => {
  await undefined; // yield until the microtasks run
  let i = 0;
  while(i < 1000000000) { i++; }
  return ' billion loops done';
}

log(' Synchronous 1');
notBlocked().then(log);
log(' Synchronous 2');

为了运行另一个worker中的函数我会使用setTimeout函数。为此,我创建了 util 函数 detach

const tick = Date.now();
const log = (v) => console.log(`${v} \n Elapsed: ${Date.now() - tick}ms`);

// Run a function in another worker.
const detach = (fn) => {
    return new Promise((resolve) => {
        setTimeout(() => {
            fn();
            resolve();
        }, 0);
    });
}

const runLoop = () => {
    let i = 0;
    while(i < 1000000000) { i++; }
    return ' billion loops done';
}

const notBlocked = async () => {
    await detach(runLoop);
}

// Enable the use of async/await (assuming your in a module and not in an async function)
(async () => {
    log(' Synchronous 1');
    const promiseNotBlocking = notBlocked(); // Get the promise
    log(' Synchronous 2');
    await promiseNotBlocking;
})()