25 строк кода для реализации функции Promise

внешний интерфейс Promise

иллюстрировать

Излишне говорить, что важность функции Promise для серверной части и интерфейса узла в значительной степени решает проблему отвратительного вложенного обратного вызова!Теперь следуйте за мной, чтобы написать простую функцию Promise!

использовать

Учитель Жуань Ифэн сказал это очень хорошо, одноклассник, который немного забылпорталвходить

Начинать

Перейдите к коду, не вдаваясь в подробности, и дайте вам возможность испытать его на себе.

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
	}
}

тестовое задание

test1

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

// 输出为hello   二秒之后输出world

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")
})
// 输出为hello world hello1  一秒之后输出over1

Основные обещания

На самом деле Promise имеет три состояния, приведенный выше код помещает состояниесъелЭто просто простая реализация его синтаксиса, теперь изменен код и добавлено состояние

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)
    }
}