function Promise(fn){
//须要一个胜利时的回调
var self = this
var callback;
//一个实例的要领,用来注册异步事宜
self.then = function(done){
callback = done;
}
// resolve 比 then 先实行 此时 callback 不存在
// 所以 加一个 setTimeout 让resolve 函数在回调行列的末端
// 为啥是0秒? 为啥处于回调行列末端?
//(威望指南)假如以0毫秒的超时时刻来挪用setTimeout(),那末指定的函数不会马上执
// 行,相反会把它放到行列中去,比及前面处于守候状况的事宜处置惩罚顺序悉数实行完成后,
// 再“马上”挪用它。
// 以下 体式格局写 提醒 resolve 未定义 触及闭包 作用域链的题目
// setTimeout(function () {
// function resolve(value){
// callback && callback(value);
// }
// }, 0)
// 革新体式格局
function resolve (value) {
setTimeout(function () {
callback && callback(value)
}, 0)
}
fn(resolve);
}
挪用promise
// 实例化promise 回调函数fn实行胜利,并实行resolve函数,此时在回调行列内里增加一
// 一个callback函数,并将resolve的参数通报出去。
var promise = new Promise(function (resolve) {
resolve(['3', 'aaa'])
})
// 挪用then函数,并实行then回调,将then函数的参数done回调函数赋值给callback,
// 在回调行列内里(之前setTimeout增加进去的回调行列)实行then的回调函数
promise.then(function (data) {
console.log('data', data)
})
然则以上体式格局写,我们永久都只能实行then中一个回调行列,这明显不硬朗。我们连系js设想形式的宣布–音讯定阅形式,再连系组织函数return this 知识点,轻微革新下:
function Promise(fn){
//须要一个胜利时的回调
var self = this
self.deferreds = []; // then函数 回调行列 贮存容器
//一个实例的要领,用来注册异步事宜
self.then = function(onFulfilled){
self.deferreds.push(onFulfilled)
console.log('self.deferreds', self.deferreds)
// 挪用两次then 回调行列会逐一push
return self // 链式挪用then
}
// 革新体式格局
function resolve (value) {
setTimeout(function () {
self.deferreds.forEach(function (deferred) {
deferred && deferred(value)
})
}, 0)
}
fn(resolve);
}
挪用then函数:
promise.then(function (data) {
console.log('data', data)
}).then(function (resp) {
console.log('resp', resp)
})
尽人皆知,组织函数Promise存在三个互斥状况:pending、fulfilled、rejected。Promise 对象的状况转变,只需两种能够:从 pending 变成 fulfilled 和从 pending 变成 rejected。只需这两种状况发作,状况就凝结了,不会再变了,会一向坚持这个效果。
所以:我们革新代码以下:
//略
// 初始化设置状况
self.status = 'pending'
//略
// ...
//略
// resolve的时刻 将状况置为
self.status = 'fulfilled'
//略
挪用实行,一样能够获得我们想要的数据。
然则
然则
然则
仅仅加上上面两行代码是不可的,细致明白加粗的那几个字,再连系我们的代码来看。
当我们挪用then函数的时刻,往我们then回调行列内里push回调函数,终究不论状况是pending
照样fulfilled,回调行列的函数都是被resolve函数触发的。如许就违犯了这句话:只需这两种状况发作,状况就凝结了,不会再变了,会一向坚持这个效果。
当我们状况转变成fulfilled,我们并没有真正转变状况,每次再从新实行的时刻,我们又从新走了一次then增加回调,然后由resolve来触发还调的历程。
所以then函数革新代码以下:
// 当status == 'pending'的时刻,我们才往then的回调行列push回调函数。
// 不然 直接实行回调函数,不会由resolve来触发then的回调函数实行。
if(self.status == 'pending') {
self.deferreds.push(onFulfilled)
return self
}
onFulfilled(value)
return self // 链式挪用then
所以到场value后,终究代码以下:
基本就完成了链式挪用then的一个带有pending 和 fulfilled 状况的Promise
后续会加上reject(), rejected以及最难明白的串行promise。
function Promise(fn){
//须要一个胜利时的回调
var self = this
self.deferreds = []; // then函数 回调行列 贮存容器
self.status = 'pending'
self.value = null
//一个实例的要领,用来注册异步事宜
self.then = function(onFulfilled){
if(self.status == 'pending') {
self.deferreds.push(onFulfilled)
return self
}
onFulfilled(self.value)
return self // 链式挪用then
}
// 革新体式格局
function resolve (newValue) {
setTimeout(function () {
self.value = newValue
self.status = 'fulfilled'
self.deferreds.forEach(function (deferred) {
deferred && deferred(self.value)
})
}, 0)
}
fn(resolve);
}