從外部改變promise內部狀態


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

這篇博文里的評論。 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM