首页 > 解决方案 > 承诺开始得太早

问题描述

我有以下承诺:

const promise = new Promise((resolve,reject) => {
  setTimeout(()=> { resolve('Hello')},4000);
});

后来,我这样称呼它:

promise.then((msg) => {console.log(msg)});

由于超时,我原以为会在呼叫后 4 秒显示“Hello”消息then,但实际上它会立即显示...

我肯定错过了什么:什么?

标签: javascriptpromise

解决方案


我这样称呼它

你不会“打电话”承诺。它不是一个函数(尽管它确实有方法)。从这个问题中,我了解到您做了第一部分(const promise = new Promise(/*...*/);),然后做了第二部分(promise.then(/*...*/);),并且您希望计时器在您执行时启动then,而不是在您执行时启动new Promise

但是 Promises 的工作方式是,你的计时器是在你做的时候开始的new Promise,而不是在你打电话的时候then。你传入的函数new Promisepromise executor函数)被同步立即调用。它的目的是启动 promise 将报告完成的操作。

这可能有助于使其更加清晰:

const start = Date.now();
function log(msg) {
    const elapsed = String(Date.now() - start).padStart(4, " ");
    console.log(`${elapsed}: ${msg}`);
}

log("A");
const promise = new Promise((resolve, reject) => {
    log("B: Starting 5000ms timer");
    setTimeout(() => {
        resolve("Hello");
    }, 5000);
    log("C");
});
log("D: Waiting 2000ms before calling `then`");
setTimeout(() => {
    log("F: Calling `then`");
    promise.then((msg) => {
        log("G");
        log(msg)
    });
}, 2000);
log("E");

注意输出是

   0: A
   1: B: Starting 5000ms timer
   2: C
   2: D: Waiting 2000ms before calling `then`
   2: E

然后大约两秒钟后:

2002: F: Calling `then`

然后大约三秒钟后(自开始以来五秒钟)

5002: G
5004: Hello

注意事项:

  • Promise 执行器立即同步运行,并启动其 5 秒计时器
  • 什么时候打电话都没关系then。我等了 2 秒,但在总共5 秒(不是 7 秒)then后仍然得到了履行回调

我上面描述的是承诺的标准行为。(不幸的是,在我看来)有少数类似于 Promise 的东西的行为略有不同,它们确实then在开始他们的过程之前等待第一次调用。这些不是典型的,但遗憾的是它们确实存在。


推荐阅读