考虑到客户端程序员既定义又使用传递给 Promise 执行器的
但是下面的代码(jsFiddle)失败了:
上述代码实际上在控制台上打印出来的内容是:
resolve
函数,我天真地认为我完全控制了 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>
上述代码实际上在控制台上打印出来的内容是:
callback called with arguments: (42, undefined)
the answer is: 42. I am not very certain about that
进一步深入研究后,我写了以下代码(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>
实际上会在控制台打印以下内容:
entering executor, resolve is: [function t() { [native code] }]
about to call "then"
about to call resolve
returning from resolve
the answer is: 42
这展示了一些有趣的事情:
- 执行器在客户端程序员有机会调用
then
之前被调用。然而,在executor
函数中的resolve
参数不是undefined
。 - 在调用
then
时传递的resolveCallback
函数与传递给executor
的resolve
函数不同。此外,它不会同步执行(即不在同一事件循环运行中)executor
函数中的resolve
调用。
Javascript 实现这个功能的唯一方法(我能想到的)是实际上插入了某种“代理”resolve
和reject
函数,这些函数与客户端程序员提供的实际resolve
和reject
函数异步连接。这也解释了为什么您无法为resolve
和reject
函数定义自己的签名:因为管道工作不起来。
这个思维模型正确吗?还是我漏掉了什么?
then
时,我不是要传递一个我选择的resolve
函数吗?我天真地认为这与executor
内部可用的resolve
函数相同,但我认为这是一个合理的假设。这个实验证明了这个假设是不成立的。我只是想确认我的心理模型。 - Marcus Junius Brutusresolve
回调时,Promise对象的状态也需要从“pending”更改为“resolved”。此外,请记住您可以在同一个promise上多次调用.then()
,并且所有这些回调都在promise解决时执行,这意味着它们进入Promise对象内部队列,并在调用resolve
时逐个调用。” - Máté Safranka