鉴于客户端程序员既定义又使用resolve传递给Promise的执行器的函数,我天真地假设我完全控制了resolve函数的签名,因此我可以定义它接受多个参数。
然而以下代码(jsFiddle)失败了:
<html>
<script>
const promise = new Promise(function executor(resolve, reject) {
setTimeout(function () {
resolve(42, true);
}, 1000);
});
promise.then(function resolveCallback(answer, howCertain) {
console.log('callback called with arguments: ('+answer+', '+howCertain+')');
console.log('the answer is: '+answer+'. I am '+(howCertain?'very':'not very')+' certain about that');
});
</script>
</html>
Run Code Online (Sandbox Code Playgroud)
上面的代码实际上打印在控制台上:
callback called with arguments: (42, undefined)
the answer is: 42. I am not very certain about that
Run Code Online (Sandbox Code Playgroud)
再深入一点,我写了下面的代码(jsFiddle):
<html>
<script>
const promise = new Promise(function executor(resolve, reject) {
console.log('entering executor, resolve is: ['+resolve+']'.);
setTimeout(function () {
console.log('about to call resolve');
resolve(42);
console.log('returning from resolve');
}, 1000);
});
console.log('about to call "then"');
promise.then(function resolveCallback(answer) {
console.log('the answer is: '+answer);
});
</script>
</html>
Run Code Online (Sandbox Code Playgroud)
它实际上在控制台上打印以下内容:
entering executor, resolve is: [function t() { [native code] }]
about to call "then"
about to call resolve
returning from resolve
the answer is: 42
Run Code Online (Sandbox Code Playgroud)
这证明了许多有趣的事情:
then。然而,函数中的resolve参数executor不是undefined。resolveCallback调用中作为参数传递then的resolve函数与传递给 的函数不同executor。此外,它不会与函数resolve内部的调用同步执行(即不在同一事件循环运行中)executor。Javascript 实现这一点的唯一方法(我能想到的)是实现实际上插入了某种“代理”resolve和reject函数,这些函数与客户端程序员提供的实际函数resolve和reject函数异步链接。这也可以解释为什么您不能为resolve和reject函数定义自己的签名:因为管道不起作用。
这种心理模型是正确的还是我遗漏了什么?
客户端程序员定义了传递给 Promise 的执行器的解析函数
不,他没有(正如您的实验所证实的那样)。执行器在new Promise创建过程中被调用。
当我调用
thenpromise 时,我不传递resolve我选择的函数吗?
不,您传递了一个onResolve侦听器回调,或者实际上是一个onFulfill回调。
我的新心智模型正确吗?
是的,地表下有更多的管道。
实际上,new Promise构造函数只为您提供代理解析器函数。
一个承诺包含一个状态机。它是一个表示(一个!)异步结果的对象。因此,您可以.then()在同一个 promise 对象上多次调用,并且回调将始终传递结果。
它不是executor函数的包装器,它不会像您调用then. 执行器只被调用一次,让生产者可以访问解析器函数(状态机的输入)。调用,观察状态机输出的消费者then与此完全解耦 - 正如您所说,它们是异步链接的。
也看看这个。对于您的心智模型,这是一个易于理解的Promise类实现(无保证的异步和错误处理)。