2015-09-12 102 views
0

我試圖動態鏈接承諾,以處理需要按順序發生的未知數量的異步調用。我使用支持Promise的IO.JS/chrome。javascript ES6動態鏈接承諾

承諾的創建立即觸發(至少相對於控制檯輸出)。我期待能夠收集承諾,然後傳遞給Promise.all,但那時他們已經因爲我不明白的原因而被解僱了。

這裏有那麼鏈接的一種方法,通過一個評論對Dynamic Chaining in Javascript Promises

  var lastPr = null; 
      console.log(" exit setup......................"); 
      while(this.statesToExit.length > 0) { 


       var v = this.statesToExit.shift(); 
       console.log("new Promise..."); 
       var pr = new Promise(function (resolve, reject) { 

        console.log("doing Exit stuff at time " +curTime); 
        resolve(); //SOMETHING MORE SUBSTANTIAL GOES HERE 

       }); 

       console.log("lastPr.then."); 
       if (lastPr != null) { 
        lastPr.then(pr); 
       } 
       lastPr = pr; 
       // console.log("adding pr to worklist"); 
       // promiseList.push(pr); 
       // }); 
      } 

提出的另一種方法是

  var promiseList= []; 
      console.log(" exit setup......................"); 
      while(this.statesToExit.length > 0) { 


       var v = this.statesToExit.shift(); 
       console.log("new Promise..."); 
       var pr = new Promise(function (resolve, reject) { 

        console.log("doing Exit stuff at time " +curTime); 
        resolve(); //SOMETHING MORE SUBSTANTIAL GOES HERE 

       }); 

       console.log("adding pr to worklist"); 
       promiseList.push(pr); 
       }); 
      } 
console.log("Transition *START*-" +promiseList.length +" "); 
     Promise.all(promiseList).catch(function(error) { 
      console.log("Part of TransitionCursor Failed!", error); 
     }).then(this.summarizeWorkDone()); 

在這兩種情況下,輸出類似

new Promise... 
doing Exit stuff at time 0 
new Promise... 
doing Exit stuff at time 0 
    "Transition *START*-" 

VS預計的

new Promise... 
new Promise... 
    "Transition *START*-" 
doing Exit stuff at time 0 
doing Exit stuff at time 0 

我該如何動態創建一個承諾列表以便稍後執行?

+0

它爲什麼無論什麼時候到底是執行承諾的身體嗎?承諾不保證他們的身體稍後會被執行。 – zerkms

+0

也許承諾不是你在這裏需要的東西,看起來像執行順序很重要,所以你想建立某種按摩隊列,然後讓它執行..但在你的例子中,如果只有一個項目statesToExit ? – webdeb

+0

你對承諾做什麼以及如何使用它們的理解看起來相當遙遠。我們可以幫助您重新構建,但需要了解是否希望所有異步操作以串行(一個接一個)或並行(全部同時開始)運行?我們還需要查看您的實際異步操作。現在你的問題中的代碼完全是同步的,因此不需要承諾。 – jfriend00

回答

-1

我承諾的理解確實關閉,這個優秀的網頁上提到:http://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html第一他們立即開始執行,第二次做動態的,你必須使用一個工廠函數推遲執行,像這樣:

首先創建鏈條開始。

var chain = Promise.resolve(); 
    //  chain.then(this.doTranStart); 

然後爲每個狀態的(一個陣列),則創建一個代理閉合,以便該函數可以被稱爲背面與相應的數據。我不確定是否有爲JavaScript內置的東西,所以我從ActionScript 2.0移植了一個庫,當它出現類似的問題時。

this.statesToExit.forEach(function (state) { 
      console.log("new Exit Promise Chain..."); 
       var pxfn = GetProxy.getProxy(self, self.doExitFactory, [curTime,state._fn,state]); 
       chain = chain.then(pxfn); 
      }); 

然後後來運行工廠鏈,然後工廠鏈,然後調用工廠,然後執行承諾。

chain.catch(function(error) { 
      console.log("Part of TransitionCursor Failed!", error); 
     }).then(this.summarizeWorkDone); 

第一個是工廠方法,很簡單。

doExitFactory(curTime,fn,stateScope) { 
     console.log("doExitFactory ");//+ curTime,fn,stateScope); 
     return this.doExit(curTime,fn,stateScope); 
    } 

這是做實際工作的功能。在給定範圍上動態調用函數。

doExit(curTime, _fn, stateScope) { 
     console.log("doExit"); 
     return new Promise(function (resolve, reject) { 
      // console.log("doing actual Exit stuff at time ");//+ curTime); 
      _fn.apply(stateScope, [{sig: STATE.EXIT}, resolve, reject]); 
      resolve(); 

     }) 
    } 

輸出類似於

TransitionCursor.setRoute 
starting to create chain 
new Exit Promise Chain... 
new Exit Promise Chain... 
finishing create chain 


calling chain to start............ 
Transition *START*-------------------------- 
doExitFactory 
doExit 
IS_s11 (EXIT) 
doExitFactory 
doExit 
IS_s1 (EXIT) 
summarizeWorkDone:--------------- 

其中IS_s11,並IS_s1是實際異步功能,我想才能運行。

-1

您寫道:

new Promise((r)=>r()).then(new Promise((r)=>r()); 

你想寫什麼:

new Promise((r)=>r()).then(()=>new Promise((r)=>r())); 

爲了使您的代碼工作,你所希望的方式,改變

lastPr.then(pr); 

lastPr.then(()=>pr); 
-1

好吧,

所以人們投我的答案,因爲我提供的外部鏈接,其實是我寫的。好難過!所以修改答案和以前的答案在這個答案的底部。

在這裏,我將重點介紹第一個例子中的問題,因爲這是我在本文底部的鏈接中解釋的。

首先:你沒有鏈接承諾,但創造了多重承諾。在創建承諾時,您傳遞給構造函數的函數會立即被調用。有關詳細信息,請參閱下面鏈接中的教程的第1部分。這就是爲什麼你在'新承諾'行後得到輸出行「在......時間內完成退出事務......」的原因。你沒有說curTime的任何內容,但似乎這些值並不正確,儘管這不是本文的重點。

其次,您應該將lastPr.then()分配給lastPr(),但您將新創建的pr分配給lastPr。以下鏈接的第2部分對此進行了解釋。

第三,我會說你的預期輸出說我應該提醒你,傳遞給promise構造函數的函數立即啓動。所以你不應該在創建promise的時候打印任何東西,而是在then()方法中將它們推下。然而,我在這裏沒有這樣做,所以你會看到第一個'在時間0行做退出的東西'行出現在第一個'新的承諾...'行之後。

第四,你沒有顯示'lastPr.then'。在預期輸出

注:我改變你的代碼的CURTIME和statesToExit(刪除「這個」參考和指定的測試陣列)

我建議是這樣的:

var curTime = 0; 
var lastPr = null; 
console.log(" exit setup......................"); 
var statesToExit = [1, 2, 3]; // NOTE: the change to make this code runnable. 
while (statesToExit.length > 0) { 
    var v = statesToExit.shift(); 
    console.log("new Promise..."); 

    if (lastPr == null) { 
     lastPr = new Promise(function (resolve, reject) { 
      console.log("doing Exit stuff at time " + curTime); 
      resolve(); //SOMETHING MORE SUBSTANTIAL GOES HERE 
     }); 
    } 
    else { 

     console.log("lastPr.then."); // NOTE: This does not appear in your expected output 
     lastPr = lastPr.then(result => { 
      console.log("doing Exit stuff at time " + curTime); 
      return Promise.resolve(); //SOMETHING MORE SUBSTANTIAL GOES HERE 
     }); 
    } 
    // console.log("adding pr to worklist"); 
    // promiseList.push(pr); 
    // }); 
} 

// NOTE: now you need to esecute the chain: 
// you should handle promise rejection: 
// check the tutorial link: 
// https://github.com/tuhinpaul/syp-model/wiki/Programmatic-Chaining-and-Recursive-Functions-with-JavaScript-Promise 
lastPr.catch(err => { console.log(err); }); 

的輸出以上代碼:

exit setup...................... 
new Promise... 
doing Exit stuff at time 0 
new Promise... 
lastPr.then. 
new Promise... 
lastPr.then. 
doing Exit stuff at time 0 
doing Exit stuff at time 0 

我在下面的教程中描述了動態承諾鏈接:檢查以下內容教程

  1. javascript/node的編程(動態)鏈接。JS承諾和
  2. 無極鏈接使用遞歸函數

Programmatic-Chaining-and-Recursive-Functions-with-JavaScript-Promise

+0

指向外部教程並不是一個合適的答案 - 這就是人們投票的原因。你應該在答案的正文中回答這個問題。 –

+0

謝謝@Mark_M通知。在這裏獲得投票是令人失望的,因爲我已經在我的鏈接中明確地解決了這個頁面的問題。我只是不想在這裏重複同樣的答案。但是,我會添加到我的答案。 –

+1

現在檢查,老兄! –