based on the easy implementation of Promise
: https://www.promisejs.org/implementing/
var PENDING = 0;
var FULFILLED = 1;
var REJECTED = 2;
function Promise(fn) {
// <-----------how can these two local variable maintain state between function calls?
var state = PENDING;
var value = null;
//
// store sucess & failure handlers
var handlers = [];
function fulfill(result) {
state = FULFILLED;
value = result;
handlers.forEach(handle);
handlers = null;
}
function reject(error) {
state = REJECTED;
value = error;
handlers.forEach(handle);
handlers = null;
}
function resolve(result) {
try {
var then = getThen(result);
if (then) {
doResolve(then.bind(result), resolve, reject)
return
}
fulfill(result);
} catch (e) {
reject(e);
}
}
function getThen(value) {
var t = typeof value;
if (value && (t === 'object' || t === 'function')) {
var then = value.then;
if (typeof then === 'function') {
return then;
}
}
return null;
}
function handle(handler) {
if (state === PENDING) {
handlers.push(handler);
} else {
if (state === FULFILLED &&
typeof handler.onFulfilled === 'function') {
handler.onFulfilled(value);
}
if (state === REJECTED &&
typeof handler.onRejected === 'function') {
handler.onRejected(value);
}
}
}
this.done = function (onFulfilled, onRejected) {
// ensure we are always asynchronous
setTimeout(function () {
handle({
onFulfilled: onFulfilled,
onRejected: onRejected
});
}, 0);
}
this.then = function (onFulfilled, onRejected) {
var self = this;
return new Promise(function (resolve, reject) {
return self.done(function (result) {
if (typeof onFulfilled === 'function') {
try {
return resolve(onFulfilled(result));
} catch (ex) {
return reject(ex);
}
} else {
return resolve(result);
}
}, function (error) {
if (typeof onRejected === 'function') {
try {
return resolve(onRejected(error));
} catch (ex) {
return reject(ex);
}
} else {
return reject(error);
}
});
});
}
doResolve(fn, resolve, reject); // <-----------------partA
}
function doResolve(fn, onFulfilled, onRejected) {
var done = false;
try {
fn(function (value) {
if (done)
return
done = true
onFulfilled(value)
}, function (reason) {
if (done)
return
done = true
onRejected(reason)
})
} catch (ex) {
if (done) return
done = true
onRejected(ex)
}
}
let promise = new Promise(function (resolve, reject) {
resolve(1);
}).then(result => console.log(result * 2),reason => { console.log(reason) });
I don't understand how local variables inside the Promise
function can maintain state. As you can see, when we new up a promise:
let promiseA = new Promise(function (resolve, reject) {
resolve(1);
})
.then(result => console.log(result * 2),reason => { console.log(reason) });
after partA call is done, the first function Promise(fn)
call has been finished , then promiseA.then()
is called, note that a new Promise
instance is created, i.e the Promise
fucntion call function Promise(fn)
is called again, so my understanding is that those local variable state
and value
are re-created on the stack, so how can they be used again by the new promise instance to get the state and value in the second function call?
P.S someone said it is about closure, but I don't see any closure here, isn't that closure is something like:
function foo() {
const secret = Math.trunc(Math.random() * 100)
return function inner() {
console.log(`The secret number is ${secret}.`)
}
}
but in the 'Promise' function, it doesn't return any function to the newly created promise instance