иллюстрировать
Излишне говорить, что важность функции 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)
}
}