promise是什么?
1、主要用於異步計算
2、可以將異步操作隊列化,按照期望的順序執行,返回符合預期的結果
3、可以在對象之間傳遞和操作promise,幫助我們處理隊列
為什么會有promise?
為了避免界面凍結(任務)
-
同步:假設你去了一家飯店,找個位置,叫來服務員,這個時候服務員對你說,對不起我是“同步”服務員,我要服務完這張桌子才能招呼你。那桌客人明明已經吃上了,你只是想要個菜單,這么小的動作,服務員卻要你等到別人的一個大動作完成之后,才能再來招呼你,這個便是同步的問題:也就是“順序交付的工作1234,必須按照1234的順序完成”。
-
異步:則是將耗時很長的A交付的工作交給系統之后,就去繼續做B交付的工作,。等到系統完成了前面的工作之后,再通過回調或者事件,繼續做A剩下的工作。
AB工作的完成順序,和交付他們的時間順序無關,所以叫“異步”。
而官方文檔則表示
Promise 對象的狀態不受外界影響。Promise 對象代表一個異步操作,有三種狀態:Pending(進行中)、Resolved(已完成,又稱 Fulfilled)和 Rejected(已失敗)。只有異步操作的結果,可以決定當前是哪一種狀態,任何其他操作都無法改變這個狀態。這也是 Promise 這個名字的由來,它的英語意思就是「承諾」,表示其他手段無法改變。
但是經過實際測試從外部控制promise狀態的事其實是可以辦到的:
1、Promise的狀態取決於promise主體中是否調用了resolved或者reject或者在調用resolved和reject前就發生異常(將會直接進入 reject狀態)
2、Promise也是js對象(雖然它實際是個函數)、逃不開按地址引用帶來的副作用,調用reject,但是沒有設置fn的reject,或者catch,故會報錯。Promise允許不設置resolved方法(即如果直接調用obj.ok()是沒問題的,不會報錯,promise狀態也會變為resolved)、但如果出現異常或者主動調用進入reject而沒有設置reject方法 或catch方法,則會報錯。
具體實現代碼demo
let obj = {} // 用於保存promise里的resolve和reject方法 let a = function(){ let p = new Promise(function(resolve,reject){ obj.ok = resolve; obj.cancel = reject; }); return p; } async function test () { // 使用async/await測試效果 console.log('test開始') let c = await a(); console.log(c) console.log('test結束'); } test() setTimeout(function(){ obj.ok('哈哈哈哈哈') },2000)
結果為
試驗證明在promise外部通過地址引用的方式進行改變promise內部狀態是可以實現的。
思路來源於
https://segmentfault.com/u/joey_5a961933efd3e
這位老哥在
https://segmentfault.com/q/1010000011145129
這篇博文里的評論。