instructions

It goes without saying how important the Promise function is to both the back end and the front end of Node, largely eliminating the nasty nested callbacks! Now follow me as I write a simple Promise function!

use

Ruan Yifeng teacher said very good, a little forget the studentsportalin

start

Go straight to the code without wordy, give you a look to experience yourself

class PromiseAProto {
	then(resolve, reject){
		this.resolves = (this.resolves || []).concat(resolve || [])
		this.rejects = (this.rejects || []).concat(reject || [])
		return this;
	}
}
class PromiseA extends PromiseAProto{	
	constructor(cb){
		super(cb)
		cb(() => {
			setTimeout(() => {
				var resolve = this.resolves.shift();
				var ret = resolve && resolve();
				if (this.isPromiseA(ret)) {
					Object.assign(ret, this)
				}
			}, 0)
		})
	}
	isPromiseA(cb){
		return cb instanceof this.constructor
	}
}
Copy the code

test

test1

new PromiseA((resolve, reject) => { resolve() console.log('hello'); }).then(() => {setTimeout(() => {console.log("world")}, 2000)}Copy the code

test2

new PromiseA((resolve, reject) => { resolve() console.log('hello'); }).then(() => { console.log("world") return new PromiseA((resolve) => { setTimeout(() => { resolve(); }, 1000) console.log("hello1")})}). Then (() => {console.log("over1")}Copy the code

Basic version of the Promise

Promise actually has three states. The code above ate the states and simply implemented the syntax. Now the code changes to add states

const PENDING = "pending";
const RESOLVED = "resolved";
const REJECTED = "rejected";
let PromiseA = function(fn){
    this.status = PENDING;
    this.value = null;
    this.resolveds = [];
    this.rejecteds = [];
    fn(this.doResolve.bind(this), this.doReject.bind(this))
}
PromiseA.prototype.doResolve = function(value){
    setTimeout(() => {
        if (this.status == PENDING) {
            this.status = RESOLVED;
            this.value = value;
            this.resolveds.map(resolve => resolve(this.value))
        }
    }, 0)
}
PromiseA.prototype.doReject = function() {setTimeout(() => {
        if (this.status == PENDING) {
            this.status = RESOLVED;
            this.value = value;
            this.rejecteds.map(reject => reject(this.value))
        }
    }, 0)
}
PromiseA.prototype.then = function(resolve, reject){
    if (this.status == PENDING) {
        this.resolveds.push(resolve)
        this.rejecteds.push(reject)
    }
    if (this.status == RESOLVED) {
        return resolve(this.value)
    }
    if (this.status == REJECTED) {
        return reject(this.value)
    }
}
Copy the code