let promise = new Promise((resolve111, reject) => { //這裏放入咱們要執行的函數,多是同步,也多是異步, 這裏咱們就來寫一個異步的執行 setTimeout(() => { resolve111('hello'); }, 100) }) promise.then(data => { console.log(data); return new Promise(function(res, rej) { setTimeout(function() { console.log(2); res(); }, 100) }) }, err => {console.log(err)})
promise的執行流程如以下:
promise
var i = 1 function Promise(fn) { this.id = i++; this.status = 'PENDING'; this.value = null; this.deffered = []; fn.call(this, this.resolve.bind(this), this.reject.bind(this)) } Promise.prototype = { constructor: Promise, then: function(onfulfilled, onrejected) { var obj = { onfulfilled: onfulfilled, onrejected: onrejected } obj.promise = new this.constructor(function() {}); console.log(this.status) if (this.status === 'PENDING') { this.deffered.push(obj); } console.log(this.deffered) return obj.promise; }, resolve: function(data) { this.status = 'FULFILLED'; this.value = data; this.deffered.forEach(item => { let p = item.onfulfilled(this.value); if (p && p.constructor === Promise) { p.deffered = item.promise.deffered; } }); }, reject: function(err) { this.status = 'REJECTED'; this.value = err; this.deffered.forEach(item => { let p = item.onrejected(this.value); if (p && p.constructor === Promise) { p.deffered = item.promise.deffered; } }); } }
then方法須要返回一個新的子Promise, 而且先後的Promise須要創建聯繫,才能決定他們的執行順序。這裏用id標識每一個promise。異步
Promise鏈式操做中,執行順序是如何保證的函數
每一個promise後面鏈一個對象該對象包含onfulfiled,onrejected,子promise三個屬性,當父promise 狀態改變完畢,執行完相應的onfulfiled/onfulfiled的時候呢,拿到子promise,在等待這個子promise狀態改變,再執行相應的onfulfiled/onfulfiled。依次循環直到當前promise沒有子promise
如何讓異步的value在thenable函數中拿到this
將resolve/reject函數和onfulfiled/onrejected放入同一個對象(promise對象)裏面,resolve/reject的時候將value設置this.value=xxx。onfulfiled/onrejected執行的時候呢,onfulfiled(this.value)便可。
在這裏避免頭暈,解釋一下,onfulfilled和onrejected指的是then裏面的兩個函數。spa
狀態機制切換prototype
如圖所示,狀態只能由pengding-->fulfilled,或者由pending-->rejected這樣轉變。 只要這兩種狀況發生,狀態就凝固了,不會再變了,會一直保持這個結果。就算改變已經發生了,你再對Promise對象添加回調函數,也會當即獲得這個結果。這與事件(Event)徹底不一樣,事件的特色是,若是你錯過了它,再去監聽,是得不到結果的。