“then”函数返回的 promise 是否与此“then”函数中的回调返回的 promise 相同?

Is the promise returned by the 'then' function the same as the promise returned by the callback inside this 'then' function?

提问人:curiousmind 提问时间:7/12/2023 最后编辑:Bergicuriousmind 更新时间:7/12/2023 访问量:47

问:

所以,我最近被介绍给 promise 的概念,我被告知出于链接目的,我们使用 'then',它实际上是在附加的 promise 对象实现时调用的。而且,为了在解析此对象后做一些工作,我可以在里面有一个回调,然后再次可以返回 promise。 因此,如果 'then' 函数中的这个 cb 返回一个 promise,而 'then' 本身返回一个 promise,那么,这是否意味着 'then' 函数从 cb 中获取这个 promise 并直接按原样返回它。 代码如下:

let p2;

function firstpromise() {
  return new Promise((resolve, reject) => {
    setTimeout
      (
        () => {
          console.log("first promise completed");
          resolve("first promise resolved");
        }, 10000
      );
  });
}
const p = firstpromise();
const pro = p.then((data) => {
  p2 = new Promise((resolve, reject) => {
    setTimeout
      (
        () => {
          console.log("second promise completed" + data);
          resolve("second promise resolved");
        }, 5000
      );
  });
  return p2;
});

console.log(pro === p2);

一旦承诺得到解决,pro 和 p2 在控制台上都会给出相同的结果,所以这让我认为 pro 和 p2 是相同的。 为了简化我的困惑: 当我写fun1(fun2);我正在调用 fun1 函数并在其中传递 fun2。现在,它是否调用 fun2 取决于 fun1。假设调用了 fun2 并向 fun1 返回了“hello”。但 fun1 可能会向我们报回“再见”。因此,在这段时间里,我们一直没有意识到 fun2 返回的任何值。 所以我的问题是函数“then”返回了一个 promise,但它在内部调用了 secondPromise 函数,该函数本身“将 promise 返回给 then function”,那么它是否意味着“然后”,因为它被向前返回,第二个 promise 函数返回给它的相同 promise? 此外,console.log(pro===p2);实际上打印 false。 如果有人能特别解释一下内部情况,那将是一个很大的帮助。;)

javascript 回调 es6-promise 异步 javascript

评论

1赞 Konrad 7/12/2023
.then立即创建新承诺
1赞 Bergi 7/12/2023
"我们使用'then',它实际上是在附加的 promise 对象实现时调用的。-不。promise 中没有魔法,该方法在调用它时立即被调用并立即返回。它是您作为参数传递的回调,稍后将在 promise 实现时调用。仅此一项就意味着它不能返回只会在将来创建的 promise,它会立即创建一个单独的 promise,稍后解析为相同的结果。请注意,当您登录时,这仍然是!.then()p2undefined
0赞 Bergi 7/12/2023
我确定以前有人问过这个问题,但我找不到一个好的副本。stackoverflow.com/q/34094806,stackoverflow.com/q/35747957,stackoverflow.com/q/65539446,stackoverflow.com/q/44765714 只是触及这个话题,但不要关注它

答:

0赞 Barmar 7/12/2023 #1

摘自 Promise.prototype.then() 的文档

实例的方法最多包含两个参数:用于 的已实现和已拒绝情况的回调函数。它会立即返回一个等效的对象,允许您将调用链接到其他 promise 方法。then()PromisePromisePromise

请注意,它会立即返回,它不会等待回调返回。因此,除非它能够预测未来,否则它不可能返回回调返回的相同 promise。

它等效的 promise 是它被调用的 promise,而不是回调返回的 promise。

评论

0赞 Bergi 7/12/2023
你说的“它等同于的承诺”是什么意思?
0赞 Barmar 7/12/2023
当文档说“它返回一个等效的 Promise 对象”时,它表示它返回一个与被调用的 promise 等效的 promise。.then()
0赞 Barmar 7/12/2023
例如 返回等效于 的 promise。promise1.then()promise1
0赞 Bergi 7/12/2023
但是 OP 谈论的是传递回调的情况,即 或者更具体地说,其中肯定不等价于 。promise1.then(…)promise3 = promise1.then(… => { …; return promise2; })promise3promise1
0赞 Barmar 7/12/2023
这个承诺是无关紧要的。上述文档中的文本指的是当时的承诺。我没有包括整个段落。
0赞 Karl-Johan Sjögren 7/12/2023 #2

简而言之,从 返回的 promise 与回调中返回的 promise 不同。当您调用 promise 时,会立即返回一个新的 promise,该 promise 在回调运行后被解析(或拒绝)。then()then()

由于 promise 是异步的,因此它不能等待回调被处理后再返回任何内容(如果基本 promise 从未解析,则永远不会处理它们)。如果是这样的话,那么链式承诺永远不能对前一个承诺的结果起作用(比如从外部源获取数据)

下面是一个示例,说明如果需要等待回调会发生什么情况。

// Fetch returns a promise which will resolve when the request is done
const promise1 = fetch('example.com');

// Adding another promise to the chain with .then() is simply saying
// "when the previous promise resolves, do this next". In this case the
// next thing would be to parse the result as json. Since this callback
// depends on the response from fetch, it can't be called until the response
// is available.
// response.json() in turn returns a new promise (much like in your example)
// which will resolve when the json is fully loaded and parsed.
const promise2 = promise1.then(response => response.json());

// when the data has been parsed, maybe we process it or log it or something
const promise3 = promise2.then(data => { /* Process data */ });

// Logging promise3 here will show a pending promise, which is waiting
// for all the previous promises to execute since it is part of the "chain"
// and when we get here "fetch" is most likely just starting the request
// and no callbacks will have been called yet, but we still have a promise
// of a future resolt of some sort.
console.log(promise3);

编号: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then