Promise對象--Mr.Emberajax
摘要json
所謂promise,簡單來講就是一個容器,裏面保存着某個將來纔會結束的事件(一般是一個異步操做)數組
promise對象有一下特色:promise
1. 對象的狀態不受外界影響異步
2. 一旦狀態改變就不會再變,任什麼時候候均可以獲得這個結果。async
有了promise對象,就能夠將異步操做以同步操做的流程表達出來,避免了層層嵌套函數。函數
Promise.prototype.then()this
p.then((val) => console.log('fulfilled:', val)) .catch((err) => console.log('rejected', err)) //等同於 p.then((val) => console.log('fulfilled:', val)) .then(null, (err) => console.log('rejected', err))
Promise.all()spa
Promise.all將多個Promise實例包裝成一個新的Promise實例。prototype
var p = Promise.all([p1, p2, p3]);
var p = Promise.all([p1, p2, p3]);
上述代碼中,只要p1, p2, p3有一個實例率先改變狀態,p的狀態就跟着改變。那個率先改變Promise的實例的返回值就傳遞給p的回調函數。
Promise.resolve()
有時須要將現有的對象轉爲Promise對象,Promise.resolve方法就起到了這個做用。
var jsPromise = Promise.resolve($ajax('/whatever.json'));
var p = Promise.reject('出錯了') //等同於 var p = new Promise((resolve, reject) => reject('出錯了')
p.then(null, function(s){
console.log(s)
})
Promise.done()
不管Promise對象的回調鏈以then的方法仍是catch的方法結尾,只要最後一個放大拋出錯誤,都有可能沒法捕捉到(由於Promise內部錯誤不會冒泡到全局)。爲此咱們能夠提供一個done方法,它老是處於回調鏈的尾端,保證拋出任何可能出現的錯誤。
asyncFunc() .then(f1) .catch(r1) .then(f2) .done();
Promise.prototype.done = function (onFulfilled, onRejected) { this.then(onFulfilled, onRejected) .catch(function(reason) {
//全局拋出一個錯誤 setTimeout(() => {throw reson}, 0); }) }
Promise.finally()
finally方法用於指定Promise對象最後狀態如何都會執行的操做。他與done的區別在於,它接受一個普通的回調函數做爲參數,該函數無論什麼狀態都會執行。
function MyPromise(fn) { var _this = this; //用來保存then傳入的回調函數 this.callback = []; //處理 第一個resolve有效 this.isResolved = false; function resolve(val) { if(_this.isResolved) return; _this.isResolved = true; if(_this.callback.length > 0) { _this.callback.forEach(item => { // func && func(val) var res, cb = item.cb, resolve=item.resolve; cb && (res = cb(val)) if(typeof res === 'object' && res.then) { res.then(resolve) }else { resolve && resolve(res) } }); } } fn(resolve); } MyPromise.prototype.then = function(cb) { var _this = this; return new MyPromise(function(resolve) { _this.callback.push({ cb: cb, resolve: resolve }) }) } var p = new MyPromise(function(resolve) { console.log(1) setTimeout(function() { resolve(2) resolve(4) resolve(5) resolve(6) }, 1000) }) p.then(function(val) { console.log(val) return new MyPromise(function(resolve) { setTimeout(function() { resolve(val + 1) }, 1000) }) }).then(function(val) { console.log(val) })
打印結果
先打印1,過了一秒打印2,再過一秒打印3