完成的一個簡樸的ES6 Promise(假如有毛病的處所,願望人人能夠不吝賜教)
僅完成Promise及.then要領
最下方有完整代碼
最先
一個
promise
對象吸收的是一個
callback
這個
callback
吸收兩個參數
(resolve,reject)
當我們在
callback
內實行
resolve
或
reject
的時刻,就會挪用
Promise
內定義的
resolve
和
reject
函數然後,
resolve
和
reject
函數會轉變Promise的狀況所以它應該是像下面如許的
function MyPromise(callback) {
// 保留this值
var self = this
// 紀錄狀況null為pending,true為resolved,false為reject
var state = null
// 紀錄resolve的參數
var param = null
// 實行傳入的callback並轉變promise對象狀況
callback(resolve, reject)
// resolve要領
function resolve(data) {
// 轉變狀況
state = true
param = data
}
// reject要領
function reject(err) {
state = false
param = err
}
}
但沒有
then
要領的
Promise
對象是不完整的(完整沒有用)所以我們須要一個
then
要領,要記着
then
要領返回的也是一個
promise
對象
then
要領吸收兩個可選的參數
(onFulfilled, onRejected)
(我們能夠先疏忽可選兩個字)
then
要領傳進來的參數必需是函數,假如不是就要疏忽(PromiseA+範例)(我們能夠也先疏忽這句話)
this.then = function (onFulfilled, onRejected) {
// 返回一個新的promise對象
return new self.constructor(function (resolve, reject) {
// then
})
}
接下來就是
then
要領的詳細完成了
then
要領中
onFulfilled, onRejected
的返回值會作為新promise的實行效果
onFulfilled, onRejected
這兩個函數要在promise
的狀況變成pending或resolved的時刻才離別實行
所以假如promise
要領狀況為resolved
或rejected
的話,我們就能夠直接在then要領中實行resolve(onFulfilled(param))
和reject(onRejected(param))
this.then = function (onFulfilled, onRejected) {
// 返回一個新的promise對象
return new self.constructor(function (resolve, reject) {
if (state === true) {
// param是promise對象完成后的效果
resolve(onFulfilled(param))
} else if (state === false) {
reject(onRejected(param))
} else {
// 沒有實行終了,怎麼辦
}
})
}
但假如
promise
的狀況為
pending
呢因為原始
promise
的狀況我們是沒法動態獵取的,因而我們就須要在他實行狀況轉變的時刻同時實行
onFulfilled
和
onRejected
要領我們能夠把這個要領放在原始
promise
對象的
resolve
和
reject
要領中實行因而我們要在
promise
的對象定義中增加四個參數,離別紀錄
onFulfilled
和
onRejected
,以及
then
要領返回的新
promise
對象的
resolve
和
reject
然後假如實行
then
要領的時刻
promise
對象的狀況為
pending
的話,就將上述四個參數紀錄起來
// then要領返回的promise對象的resolve和reject
var nextResolve = null
var nextReject = null
// 紀錄then要領的參數,onFulfilled和onRejected
var asynconFulfilled = null
var asynconRejected = null
//then要領
this.then = function (onFulfilled, onRejected) {
// 返回一個新的promise對象
return new self.constructor(function (resolve, reject) {
if (state === true) {
// param是promise對象完成后的效果
resolve(onFulfilled(param))
} else if (state === false) {
reject(onRejected(param))
} else {
nextResolve = resolve
nextReject = reject
asynconFulfilled = onFulfilled
asynconRejected = onRejected
}
})
}
接下來就是原始
promise
中的
resolve
和
reject
的從新完成
// resolve要領
function resolve(data) {
// 轉變狀況
state = true
param = data
nextResolve(asynconFulfilled(param))
}
// reject要領
function reject(err) {
state = false
param = err
nextReject(asynconRejected(param))
}
很簡樸不是嗎
我們繼承
上述完成我們一向沒有斟酌一個很主要的狀況,假如
then
要領返回的照樣一個
promise
對象,那末假如我們後邊另有
then
要領的話就要守候前一個
then
要領中的
promise
對象的狀況從
pending
變成完成這要怎麼做呢
什麼時刻能夠以為then要領返回的
promise
對象實行終了了呢,這裏我們就要用到
then
要領(@_@,邊寫邊用…),以
resolve
要領為例
var self = this
// resolve要領
function resolve(data) {
// 紀錄onFulfilled的實行效果
let parmise
// 轉變狀況
state = true
param = data
// 實行紀錄的onFulfilled
parmise = asynconFulfilled(param)
if(parmise === undefined){
// 假如parmise為undefined,就不能剖析parmise.constructor
} else if (parmise.constructor === self.constructor) {
// 守候通報進來的promise對象實行終了,然後依據通報進來的promise對象的狀況實行resolve或reject
// 注重,這個param是形參,在then要領的promise中實行
promise.then(function (param) {
resolve(param)
}, function (param) {
reject(param)
})
} else {
// 這個是前邊的then返回的不是promise對象的狀況
resolve(promise)
}
}
前面我們疏忽了兩點 (
then
要領吸收兩個可選的參數(onFulfilled, onRejected)
) 和 (
then
要領傳進來的參數必需是函數,假如不是就要疏忽)
var self = this
// resolve要領
function resolve(data) {
// 紀錄onFulfilled的實行效果
var parmise
// 轉變狀況
state = true
param = data
// 實行紀錄的onFulfilled
// begin--------------
if (typeof onFulfilled === 'function') {
promise = onFulfilled(param)
if (promise === undefined) {
// 待補充
} else if (promise.constructor === self.constructor) {
// 注重,這個param是形參,在then要領的promise中實行
promise.then(function (param) {
resolve(param)
}, function (param) {
reject(param)
})
} else {
reject(promise)
}
} else {
// 假如onFulfilled不是function,疏忽,直接resolve或reject
resolve(param)
}
// ---------------end
}
上面begin到end之間的代碼還要在
then
要領挪用,所以我們能夠把這段代碼籠統為一個函數
resolve
和
reject
的道理雷同,只需注重
假如不是function 的話須要實行reject
onFulfilled
和
onRejected
只要在[實行環境]客棧僅包括
平台代碼時才可被挪用所以將上述
begin-end之間的代碼放到
seTimeout
中實行(瀏覽器環境)
function resolve(data) {
// 紀錄onFulfilled的實行效果
var parmise
// 轉變狀況
state = true
param = data
// 實行紀錄的onFulfilled
window.setTimeout(function () {
// begin--------------
// 上述代碼
// ---------------end
}, 0)
}
下面是完整代碼
注:沒有完成準確的事宜輪迴
// 簡樸完成ES6 Promise
function MyPromise(callback) {
// 保留this值
var self = this
// 紀錄狀況null為pending,true為resolved,false為reject
var state = null
// 紀錄resolve的參數
var param = null
// then要領返回的promise對象的resolve和reject
var nextResolve = null
var nextReject = null
// 紀錄then要領的參數,onFulfilled和onRejected
var asynconFulfilled = null
var asynconRejected = null
// 實行並轉變promise對象狀況
callback(resolve, reject)
// then要領
this.then = function (onFulfilled, onRejected) {
// 返回一個新的promise對象
return new self.constructor(function (resolve, reject) {
// 推斷異步代碼是不是實行終了(是不是resolve或reject)
// 若實行終了就在then要領中馬上實行,否則將四個參數紀錄下來,守候state停當后再實行doAsyn*函數
if (state === true) {
doAsynconFulfilled(onFulfilled, resolve, reject)
} else if (state === false) {
doAsynconRejected(onRejected, resolve, reject)
} else {
nextResolve = resolve
nextReject = reject
asynconFulfilled = onFulfilled
asynconRejected = onRejected
}
})
}
// resolve要領
function resolve(data) {
// 轉變狀況
state = true
param = data
if(nextResolve){
doAsynconFulfilled(asynconFulfilled, nextResolve, nextReject)
}
}
// reject要領
function reject(err) {
state = false
param = err
if(nextReject){
doAsynconRejected(asynconRejected, nextResolve, nextReject)
}
}
// 中心要領(我以為是)
function doAsynconFulfilled(onFulfilled, resolve, reject) {
window.setTimeout(function () {
// 推斷onFulfilled是不是為function,不是則疏忽
if (typeof onFulfilled === 'function') {
// 實行onFulfilled要領獵取返回值promise()
let promise = onFulfilled(param)
// 假如promise為undefined 實行 if
// 假如promise為MyPromise對象 實行 else if
// 假如promise為非MyPromise對象 實行 else
if (promise === undefined) {
resolve(param)
// 待補充
} else if (promise.constructor === self.constructor) {
// 守候通報進來的promise對象實行終了,然後依據通報進來的promise對象的狀況實行resolve或reject
promise.then(function (param) {
resolve(param)
}, function (param) {
reject(param)
})
} else {
// 實行then要領返回的對象的resolve
resolve(promise)
}
} else {
// 通報參數
resolve(param)
}
}, 0)
}
function doAsynconRejected(onRejected, resolve, reject) {
window.setTimeout(function () {
if (typeof onRejected === 'function') {
let promise = onRejected(param)
if (promise === undefined) {
reject(param)
// 待補充
} else if (promise.constructor === self.constructor) {
promise.then(function (param) {
resolve(param)
}, function (param) {
reject(param)
})
} else {
reject(promise)
}
} else {
// 通報毛病信息
reject(param)
}
}, 0)
}
}
// 測試運用
var b = function (message) {
return new MyPromise(function (resolve, reject) {
document.body.onclick = function () {
resolve('click:' + message)
}
})
}
var a = new MyPromise(function (resolve, reject) {
resolve(123)
}).then(function (message) {
return b(message)
}).then().then(function (message) {
console.log('final:' + message)
},function (err) {
console.log('final:' + err)
})
console.log('window')
固然另有Promise.all等要領。
終了!