在 setTimeout 中使用异步有效吗?

Is using async in setTimeout valid?

我在 Javascript 中有一个异步函数,我向它添加了 setTimeout。代码如下所示:

        let timer;
        clearTimeout(timer);
        timer =setTimeout(() => {
        (async() => {
            await this._doSomething();
        })();
        }, 2000);

setTimeout 的目的是在函数 运行 之前添加 2 秒。确保用户停止输入。

我现在是否应该从此函数中删除 async/await,因为 setTimeout 无论如何都是异步的?

/* contrived example alert */
var foo = 'poo';
function setFoo(callback) (
    setTimeout(function(){
        foo = 'bar';
        callback();
    }, 100);
);
setFoo(function() {
    alert(foo);
});

setTimeout 在 函数调用之前添加延迟 ,而 async/await是 promise 之上的语法糖,一种在 调用完成后将代码链接到 运行 的方法,所以它们是不同的。

setTimeout 具有糟糕的错误处理特性,因此我建议在所有代码中使用以下内容:

let wait = ms => new Promise(resolve => setTimeout(resolve, ms));

然后再也不会直接调用 setTimeout

您的代码现在变为:

let foo = async () => {
  await wait(2000);
  await this._doSomething();
}

除了 foo 等待 doSomething 完成。这通常是可取的,但没有上下文很难知道你想要什么。如果您打算 运行 doSomething 与其他代码并行,我建议:

async () => { await Promise.all([foo(), this._otherCode()]); };

在同一个地方加入和捕获错误。

如果你真的打算开火而忘记 _doSomething 而不是等待它,你可能会失去 await,但你应该 try/catch 错误:

async () => {
  let spinoff = async () => { try { await foo(); } catch (e) { console.log(e); } };
  spinoff(); // no await!
}

但我不推荐这种模式,因为它很微妙,很容易错过。