为什么 Promise 构造函数需要一个在完成时调用“resolve"的函数,而“then"不需要——而是返回一个值? [英] Why does the Promise constructor require a function that calls 'resolve' when complete, but 'then' does not - it returns a value instead?

查看:16
本文介绍了为什么 Promise 构造函数需要一个在完成时调用“resolve"的函数,而“then"不需要——而是返回一个值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我开始研究 Promise 时,我的理解停止在以下我没有讨论过的问题上(我发现的只是对 Promise 构造函数的具体讨论,以及 Promise 'then' 函数 - 但不是比较它们的设计模式的讨论).


1.Promise 构造函数

(代码示例改编自 Jake Archibald 的经典教程.)

这是对事物运作方式的高度简化视图,省略了许多重要细节.但我认为,如果人们能够对预期目的有一个很好的概述,那么在深入了解细节时将有助于避免混淆.

一些选定的细节

立即调用执行器

一个重要的细节是传递给Promise()构造函数的执行器函数被立即调用(在构造函数返回promise之前);而传递给 then() 方法的处理函数直到 稍后(如果有的话)才会被调用.

Bergi 提到了这一点,但我想在不使用术语 a/synchronously 的情况下重申它,如果您不仔细阅读,可能会混淆:函数调用异步与异步调用之间的区别.被异步调用很容易在通信中掩饰.

resolve() 不是 onFulfill()

我想强调的另一个细节,因为它让我困惑了一段时间,resolve()reject() 回调传递给 resolve()reject()code>Promise() 构造函数的执行器函数不是之后传递给 then() 方法的回调.回想起来,这似乎很明显,但这种明显的联系让我在圈子里转了太久.肯定有联系,但它是松散的、动态的.

相反,resolve()reject() 回调是函数由系统"提供,并传递给执行程序当您创建一个承诺时,通过 Promise 构造函数来实现.当 resolve() 函数被调用时,系统代码被执行,这可能会改变承诺的状态,并最终导致 onFulfilled() 回调被异步调用.不要认为调用 resolve() 是调用 onFulfill() 的紧密包装!

As I plunge into studying Promises, my understanding has halted on the following question that I do not find discussed (all I find are specific discussions of the Promise constructor, and the Promise 'then' function - but not a discussion that compares their design patterns).


1. The Promise constructor

From the MDN documentation, we have this use of the Promise constructor (with my comment added):

new Promise(function(resolve, reject) { ... }); // <-- Call this Stage 1

Function object with two arguments resolve and reject. The first argument fulfills the promise, the second argument rejects it. We can call these functions, once our operation is completed.


2. The then function

Moving on to the then function that can be called on a Promise object (which returns a new Promise object), we have the following function signature as described by the documentation (with my comments added):

p.then(onFulfilled, onRejected);

Chaining

Because the then method returns a Promise, you can easily chain then calls.

var p2 = new Promise(function(resolve, reject) {
  resolve(1); // <-- Stage 1 again
});

p2.then(function(value) {
  console.log(value); // 1
  return value + 1; // <-- Call this Stage 2
}).then(function(value) {
  console.log(value); // 2
});


My question

From the above code snippet, it seems clear to me that the value passed to the resolve function in Stage 1 (in the second occurrence of resolve - beneath (2), above) is passed on to the next stage (the first then function that follows in the same code snippet). There is no return value at Stage 1. However, it is the return value at Stage 2 that is passed on to the next stage after that (the second then function).

Is this lack of correspondence between the design pattern for the creation of a Promise, and the use of the then function on an existing promise (which also returns a Promise), just a historical fluke (one requires calling a callback but returns nothing, and the other returns a value but does not call a callback)?

Or am I missing an underlying reason why the Promise constructor utilizes a different design pattern than the then function?

解决方案

Bergi's answer is excellent, and has been very helpful to me. This answer is complementary to his. In order to visualize the relationship between the Promise() constructor and the then() method, I created this diagram. I hope it helps somebody... maybe even me, a few months months from now.

The main idea here is that the "executor" function passed to the Promise() constructor sets tasks in motion that will set the state of the promise; whereas the handlers you pass to then() will react to the state of the promise.

(Code examples adapted from Jake Archibald's classic tutorial.)

This is a highly simplified view of how things work, leaving out many important details. But I think if one can keep a grip on a good overview of the intended purpose, it will help avoid confusion when one gets into the details.

A couple of selected details

The executor is called immediately

One important detail is that the executor function passed to the Promise() constructor is called immediately (before the constructor returns the promise); whereas the handler functions passed to the then() method will not be called till later (if ever).

Bergi mentioned this, but I wanted to restate it without using the terms a/synchronously, which can be confused if you're not reading carefully: The distinction between a function calling something asynchronously vs. being called asynchronously is easy to gloss over in communication.

resolve() is not onFulfill()

One more detail I'd like to emphasize, because it confused me for a while, is that the resolve() and reject() callbacks passed to the Promise() constructor's executor function are not the callbacks later passed to the then() method. This seems obvious in retrospect, but the apparent connection had me spinning in circles for too long. There is definitely a connection, but it's a loose, dynamic one.

Instead, the resolve() and reject() callbacks are functions supplied by the "system", and are passed to the executor function by the Promise constructor when you create a promise. When the resolve() function is called, system code is executed that potentially changes the state of the promise and eventually leads to an onFulfilled() callback being called asynchronously. Don't think of calling resolve() as being a tight wrapper for calling onFulfill()!

这篇关于为什么 Promise 构造函数需要一个在完成时调用“resolve"的函数,而“then"不需要——而是返回一个值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆