var fn = new Promise(function (resolve, reject) {
// 異步操做
setTimeout(function() {
resolve('resolve 01')
// 因爲reslove和 reject 是互斥的,由於已經調用了 resolve,這裏reject不會執行
reject('reject 01')
}, 500)
})
fn().then(function (data) {
console.log('成功1:', data)
return new Promise(function (resolve, reject) {
reject('reject 02')
}
)}, function (err) {
console.log('失敗1:', err)
})
.then(function (data) {
console.log('成功2:', data)
}, function (err) {
console.log('失敗2:', err)
}).then(function (data) {
console.log('成功2:', data)}, function (err) {
console.log('失敗2:', err)
})複製代碼
結果:前端
能夠看到,Promise 一般會有這些特性:ajax
var Promise = function (executor) {
console.log('證實不是用的原生 Promise')
var _this = this
this.status = 'pending'
// 默認狀態,能夠轉化爲 resolved 和 rejected
this.successVal = undefined
this.failVal = undefined
// 執行了成功或失敗後,要將狀態對應修改爲成功和失敗
function resolve (val) {
if ( _this.status === 'pending' ) {
_this.status = 'resolved'
_this.successVal = val
}
}
function reject (val) {
if ( _this.status === 'pending' ) {
_this.status = 'rejected'
_this.failVal = val
}
}
try {
// 應該還記得,Promise 的參數是一個函數吧,咱們稱之爲 executor(執行器)
// 同時這個函數接收2個參數,分別是成功和失敗的回調函數
executor(resolve, reject)
} catch (e) {
// 若是發生異常,直接reject捕獲
reject(e)
}
}
// then 方法接收2個參數,分別是成功和失敗的回調函數
Promise.prototype.then = function (onFulfilled, onRejected) {
var _this = this
// 顯然要根據當前狀態來執行成功或失敗的回調了
if ( _this.status === 'resolved' ) {
onFulfilled(_this.successVal)
}
if ( _this.status === 'rejected' ) {
onFulfilled(_this.failVal)
}
}複製代碼
var fn = new Promise(function (resolve, reject) {
resolve('oooook~')
})
fn.then(function (data) {
console.log('success: ', data)}, function (err) {
console.log('err: ', err)
})複製代碼
結果:編程
結果看上去很美。但若是改爲下面這樣呢?promise
var fn = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve('oooook~')
}, 500)
})
fn.then(function (data) {
console.log('success: ', data)
}, function (err) {
console.log('err: ', err)
})複製代碼
結果:
var Promise = function (executor) {
console.log('證實不是用的原生 Promise 的一句廢話')
var _this = this this.status = 'pending'
// 默認狀態,能夠轉化爲 resolved 和 rejected
this.successVal = undefined
this.failVal = undefined
// ----------------- 表示新增代碼 -------------------- // 用於存放成功和失敗的回調
this.onFulfilledList = []
this.onRejectedList = []
function resolve (val) {
if ( _this.status === 'pending' ) {
_this.status = 'resolved'
_this.successVal = val
// -------------- 執行全部的成功回調 ---------------
_this.onFulfilledList.forEach(function(fn){
fn()
})
}
}
function reject (val) {
if ( _this.status === 'pending' ) {
_this.status = 'rejected'
_this.failVal = val
// -------------- 執行全部的失敗回調 ---------------
_this.onRejectedList.forEach(function(fn){
fn()
})
}
}
try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
Promise.prototype.then = function (onFulfilled, onRejected) {
var _this = this
if ( _this.status === 'resolved' ) {
onFulfilled(_this.successVal)
}
if ( _this.status === 'rejected' ) {
onFulfilled(_this.failVal)
}
// ----------------- 對異步調用的處理 -------------------
// 說明:若是是異步調用,走到 then 方法裏的時候,status 尚未被修改,仍然
// 是 pending 狀態,因此這時候須要再回去執行 executor 裏的對應方法,而對應的
// 方法會將對應的存放回調的 list 裏的方法執行(相似發佈-訂閱模式同樣的處理)
if ( _this.status === 'pending' ) {
_this.onFulfilledList.push(function () {
onFulfilled(_this.successVal)
})
_this.onRejectedList.push(function () {
onRejected(_this.failVal)
})
}
}複製代碼
看看效果: