所謂Promise胚膊,簡單來說就是一個容器暮芭,里面保存著某個未來才會結(jié)束的事件(通常是一個異步操作)的結(jié)果。從語法上來說该互,Promise是一個對象贯涎,從它可以獲取異步操作的消息。Promise提供統(tǒng)一API慢洋,各種異步操作都可以用同樣的方法進行處理塘雳。
ES6規(guī)定,Promise 是一個構(gòu)造函數(shù)普筹,用來生成promise實例
var promise = new Promise(function(resolve, reject){
// ... some code
if (/* 異步操作成功 */) {
resolve(value)
} else {
reject(error)
}
})
Promise構(gòu)造函數(shù)接受一個函數(shù)作為參數(shù)败明,該函數(shù)的兩個參數(shù)分別是resolve和reject,它們是兩個函數(shù)太防,由js引擎提供妻顶,不需要自己部署
resolve的作用是,將Promise對象的狀態(tài)從‘未完成’變成‘成功’蜒车,也就是異步操作成功時調(diào)用讳嘱,并將操作的結(jié)果作為參數(shù)傳遞出去,reject函數(shù)與resolve相反酿愧,將Promise對象的狀態(tài)從‘未完成’變成‘失敗’沥潭,就是在異步操作失敗時時調(diào)用,并將錯誤作為參數(shù)傳遞出去
Promise實例生成以后嬉挡,可以用then方法分別指定Resolved狀態(tài)和Rejected狀態(tài)的回調(diào)函數(shù)
promise.then(function(value){
// success do something
}, function(error){
// failure do something
})
then方法可以接受兩個回調(diào)函數(shù)作為參數(shù)钝鸽,第一個回調(diào)函數(shù)是Promise對象的狀態(tài)變?yōu)镽esolved時調(diào)用,第二個回調(diào)函數(shù)是Promise對象的狀態(tài)變?yōu)镽ejected時調(diào)用庞钢。其中拔恰,第二個函數(shù)是可選的,不一定要提供基括,但是異常捕獲是考驗我們代碼健壯性必不可少的颜懊,最好是有。這兩個函數(shù)都接受Promise對象傳出的值作為參數(shù)
下面是一個Promise對象的簡單例子:
function timeout (ms) { // timeout 函數(shù)返回Promise實例
return new Promise(function(resolve, reject) {
setTimeout(resolve, ms, 'done') // Promise未來要發(fā)生的事情,這里直接將‘done’字符串作為成功的結(jié)果通過resolve函數(shù)返回出去
})
}
timeout(100).then(function(value) { // then函數(shù)第一個參數(shù)是Promise對象的狀態(tài)成功時調(diào)用河爹,在控制臺會將value打印出來使鹅,也就是我們在上面給resolve函數(shù)傳遞的‘done’字符串
console.log(value)
})
Promise新建后就會立即執(zhí)行,它會確定實例是Resolved或者Rejected狀態(tài),進而觸發(fā)對應(yīng)的回調(diào)
let promise = new Promise(function(resolve, reject){ // 立即執(zhí)行昌抠,并且打印‘Promise’
console.log('Promise')
resolve()
})
promise.then(function(){ // 異步操作要等同步操作執(zhí)行完成之后執(zhí)行患朱,所以最后打印‘Resolved’
console.log('Resolved')
})
console.log('Hi!') // js由上而下執(zhí)行同步操作,其次打印‘Hi’
/*
依次打印
Promise
Hi
Resolved
*/
Promise對象有以下兩個特點炊苫。
1裁厅、對象的狀態(tài)不受外界影響。Promise對象代表一個異步操作侨艾,有3種狀態(tài): Pending(進行中), Fulfilled(已成功) 和 Rejected(已失敗)执虹。只有異步操作的結(jié)果可以決定當(dāng)前是哪一種狀態(tài),任何其他操作都無法改變這個狀態(tài)唠梨。這也是Promise這個名字的由來袋励,它在英語種的意思就是承諾,表示其他手段無法改變。
2、一旦狀態(tài)改變就不會再變乘盖,任何時候都可以得到這個結(jié)果熬的。Promise對象的狀態(tài)改變只有兩種可能:從Pedding變成Fulfilled和從Pedding變成Rejected藻雌。只要這兩種情況發(fā)生,狀態(tài)就凝固了,不會再變,而是一直保持這個結(jié)果钾腺,這時就稱為Resolved(已定型)。就算改變已經(jīng)發(fā)生讥裤,再對Promise對象添加回調(diào)函數(shù)放棒,也會立即得到這個結(jié)果。
我們來看一個簡單的例子:
function loadImg(src) {
var promise = new Promise(function(resolve, reject) {
var img = document.createElement('img')
img.onload = function () {
resolve(img)
}
img.onerror = function () {
reject()
}
img.src = src
})
return promise
}
var src = 'https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png'
var result = loadImg(src)
result.then(function(img) {
console.log(1, img.width)
return img
}, function() {
console.log('error 1')
}).then(function(img) {
console.log(2, img.height)
})
大部分瀏覽器目前都支持Promise標(biāo)準(zhǔn)己英,部分老版本IE不支持间螟,可以在BootCDN找bluebird鏈接,在js中引入
<script src="https://cdn.bootcss.com/bluebird/3.5.3/bluebird.min.js"></script>