19

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

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

setTimeout 的目的是在函数运行前增加 2 秒。这是为了确保用户停止打字。

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

4

2 回答 2

48

setTimeout在函数调用之前添加延迟,而async/await是承诺之上的语法糖,一种在调用完成链接代码运行的方式,因此它们是不同的。

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,但您应该尝试/捕获错误:

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

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

于 2016-08-18T20:42:47.497 回答
-6
/* contrived example alert */
var foo = 'poo';
function setFoo(callback) (
    setTimeout(function(){
        foo = 'bar';
        callback();
    }, 100);
);
setFoo(function() {
    alert(foo);
});
于 2016-08-16T12:43:35.487 回答