【问题标题】:Is using async in setTimeout valid?在 setTimeout 中使用异步是否有效?
【发布时间】:2016-12-22 20:13:32
【问题描述】:

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

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

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

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

【问题讨论】:

  • “代码看起来像那样” 不太可能,这就是为什么你不应该删除 asyncawait。在这个例子中它没有意义,但这并不意味着它在实际代码中没有意义。
  • 有点不清楚你到底在问什么。 supposed 的代码是如何工作的,删除 asyncawait 会如何改变?如果没有一个明确的问题有一个实际的答案,你只会得到非常广泛和固执己见的建议。
  • 我已经编辑了问题,以更清楚地说明我想要达到的目标。

标签: javascript asynchronous settimeout ecmascript-2017


【解决方案1】:
/* contrived example alert */
var foo = 'poo';
function setFoo(callback) (
    setTimeout(function(){
        foo = 'bar';
        callback();
    }, 100);
);
setFoo(function() {
    alert(foo);
});

【讨论】:

  • 我看到了downvotes,但没有看到cmets,所以要澄清downvotes...这如何回答这个问题?而且你甚至没有使用async 函数,这就是这个问题所要问的。
  • 是的,你显然从这个关于类似主题的更有用的答案中撕下了那个 sn-p...stackoverflow.com/a/19626821/1580234
【解决方案2】:

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!
}

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-28
    • 1970-01-01
    • 2017-07-19
    • 2012-06-03
    • 2019-06-13
    • 1970-01-01
    相关资源
    最近更新 更多