How do I implement promises by hand?

Implementing promises requires A full understanding of the Promise A+ specification, but from an overall implementation perspective, there are A few things to consider:

– Promise is essentially a state machine, and the states can only be the following three: This is a big pity. The change of the state is one-way and can only be realized from Pending -> depressing or Pending -> Rejected. The state change is irreversible

-then needs to support chained calls

class Promise {

callbacks = [];

state = ‘pending’; // Add state

value = null; // Save the result

constructor(fn) {

fn(this._resolve.bind(this), this._reject.bind(this));

}

then(onFulfilled, onRejected) {

return new Promise((resolve, reject) => {

this._handle({

onFulfilled: onFulfilled || null,

onRejected: onRejected || null,

resolve: resolve,

reject: reject

});

});

}

_handle(callback) {

if (this.state === ‘pending’) {

this.callbacks.push(callback);

return;

}

let cb = this.state === ‘fulfilled’ ? callback.onFulfilled : callback.onRejected;

if (! Cb) {// If nothing is passed in then

cb = this.state === ‘fulfilled’ ? callback.resolve : callback.reject;

cb(this.value);

return;

}

let ret = cb(this.value);

cb = this.state === ‘fulfilled’ ? callback.resolve : callback.reject;

cb(ret);

}

_resolve(value) {

if (value && (typeof value === ‘object’ || typeof value === ‘function’)) {

var then = value.then;

if (typeof then === ‘function’) {

then.call(value, this._resolve.bind(this), this._reject.bind(this));

return;

}

}

this.state = ‘fulfilled’; // Change the state

this.value = value; // Save the result

this.callbacks.forEach(callback => this._handle(callback));

}

_reject(error) {

this.state = ‘rejected’;

this.value = error;

this.callbacks.forEach(callback => this._handle(callback));

}

}

Promise.resolve

Promsie.resolve(value) Can convert any value to value. The state is a fulfilled Promise, but if the value passed in is itself a Promise, it will be returned as is.

Promise.resolve(value) {

if (value && value instanceof Promise) {

return value;

} else if (value && typeof value === ‘object’ && typeof value.then === ‘function’) {

let then = value.then;

return new Promise(resolve => {

then(resolve);

});

} else if (value) {

return new Promise(resolve => resolve(value));

} else {

return new Promise(resolve => resolve());

}

}

Promise.reject

Like promise.resolve (), promise.reject () instantiates a Promise in the Rejected state. But unlike promise.resolve (), if you pass a Promise object to promise.reject (), that object becomes the value of the new Promise.

Promise.reject = function(reason) {

return new Promise((resolve, reject) => reject(reason))

}

Promise.all

All Promsie passed in are fulfilled, and a new Promise consisting of their values is returned with the state of fulfilled;

As long as one Promise is Rejected, a new Promsie with the Rejected state is returned, and its value is the value of the first Rejected Promise.

As long as either Promise is pending, a new Promise in a pending state is returned;

Promise.all = function(promiseArr) {

let index = 0, result = []

return new Promise((resolve, reject) => {

promiseArr.forEach((p, i) => {

Promise.resolve(p).then(val => {

index++

result[i] = val

if (index === promiseArr.length) {

resolve(result)

}

}, err => {

reject(err)

})

})

})

}

Promise.race

Promise.race returns a new instance wrapped with the first Fulfilled or Rejected instance among all iterable instances.

Promise.race = function(promiseArr) {

return new Promise((resolve, reject) => {

promiseArr.forEach(p => {

Promise.resolve(p).then(val => {

resolve(val)

}, err => {

rejecte(err)

})

})

})

}

Today’s content to share here first, remember to like + follow ah ~