Given that the client programmer both defines and uses the resolve
function passed to the executor of a Promise, I naively assumed that I fully control the signature of the resolve
function and so I can define it to take more than one arguments.
Yet the following code (jsFiddle) fails:
<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>
The above code actually prints on the console:
callback called with arguments: (42, undefined)
the answer is: 42. I am not very certain about that
Digging a little deeper, I wrote the below code (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>
which actually prints the following on the console:
entering executor, resolve is: [function t() { [native code] }]
about to call "then"
about to call resolve
returning from resolve
the answer is: 42
This demonstrates a number of interesting things:
- the executor is called before the client programmer has a chance to call
then
on the promise. And yet, the resolve
parameter in the executor
function is not undefined
.
- the
resolveCallback
function that is passed as argument in the call to then
is not the same as the resolve
function passed to the executor
. Moreover, it is not executed synchronously (i.e. not in the same event loop run) with the resolve
call from within the executor
function.
The only way for Javascript to pull this off (that I can think of) is that the implementation is actually plugging some sort of "proxy" resolve
and reject
functions which are asynchronously linked to the actual resolve
and reject
functions supplied by the client programmer. This would also explain why you can't define your own signature for the resolve
and reject
functions: because the plumbing won't work.
Is this mental model correct or am I missing something?
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…