25行程式碼實現Promise函式

fiveoneLei發表於2017-11-22

說明

Promise函式對node後端和前端的重要性就不必多說了,很大一部分程度上解決了噁心的巢狀的回撥!現在跟著我來寫一個簡單的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

其實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)
    }
}
複製程式碼

相關文章