2014-02-13 94 views
0

幫我理解我的代碼有什麼問題。承諾和收集迴路

所以我要做的就是調用異步調用來計數。我已經把它變成了一個承諾。

function getCount(client) { 
    var xml = "<urn:mgmtISCSIGetTargetList> </urn:mgmtISCSIGetTargetList>"; 
    client.MgmtServer.MgmtServer.mgmtISCSIGetTargetList(xml, function (err, result) { 

     if (err) { 
      logger.error(err); 
      debug(err); 
      return deferred.reject(err); 
     } 
      deferred.resolve(parseInt(result.list.targetCount)); 
     } 
    }); 

    return deferred.promise; 
}; 

一旦我使用上述承諾獲得計數,我需要進行更多的異步調用,與第一次承諾的返回次數一樣多。

假設在後面做的代碼是另一個承諾。 該代碼是:

function az(client, index) { 
    var xml = "<urn:mgmtISCSIGetTargetList> </urn:mgmtISCSIGetTargetList>"; 
    client.MgmtServer.MgmtServer.mgmtISCSIGetTargetList(xml, function (err, result) { 

      if (err) { 
       return deferred.reject(err); 
      } 

      var i; 
      for (i = 0; i < index; i++) { 
       if (1 === i) { 
        console.log('index 1 is bad news'); 
        return deferred.reject("Blew up"); 
       } 
      } 

      console.log('after the loop'); 
      deferred.resolve(index); 
     } 
    ); 
    return deferred.promise; 
}; 

只是爲了測試目的,我硬編碼爲1拒絕承諾指標。 當我將承諾放在一起時,我沒有看到我期望的。 的代碼是:

getCount(client).then(
    function (count) { 
     return az(client, count).then(console.log); 
    } 
).catch(
    function (err) { 
     console.log('caught an error from outer promise'); 
     console.log(err); 
    } 
); 

輸出我得到的是:

3 which is from deferred.resolve(index); 
index 1 is bad news which is hard coded failure. 

我知道這是一個很長的帖子,但任何人看到的東西,我在這些鏈接2個諾言一起做錯了什麼?

我改變AZ爲閱讀:

function az(client, index) { 
    var xml = "<urn:mgmtISCSIGetTargetList> </urn:mgmtISCSIGetTargetList>"; 
    client.MgmtServer.MgmtServer.mgmtISCSIGetTargetList(xml, function (err, result) { 

      if (err) { 
       return deferred.reject(err); 
      } 

      if (1 === index) { 
       console.log('index 1 is bad news'); 
       return deferred.reject("Blew up"); 
      } 

      console.log('after the loop with index ' + index); 
      deferred.resolve(index + 30); 
     } 
    ); 
    return deferred.promise; 
}; 
+0

你在哪裏構造'deferred'變量? – Bergi

+0

你使用什麼承諾庫? – Bergi

+0

vardeffered = require('Q).deferred並使用Q包並推遲 – reza

回答

1

可以解析(履行/拒絕)一個承諾只有一次。你在圈內有return deferred.reject("Blew up");看起來很像設計氣味,或者是錯誤的理解。

我需要做更多的異步調用,多達第一承諾的回報。即假設做以後的代碼是另一個承諾

每個異步任務應該有自己的諾言。我曾從該說明書預期是

getCount(client).then(function (count) { 
    for (var i=0; i<count; i++) 
     az(client, i).then(console.log); 
}) 

現在你將有一個承諾從每個az調用返回,所以你有並行執行承諾的數組。如果你需要等待所有的結果一起繼續下去,你需要把它們組合成一個新的承諾。 Q庫確實有一個幫助函數,名字爲Q.all。你可以這樣使用它:

getCount(client).then(function (count) { 
    var promises = []; 
    for (var i=0; i<count; i++) 
     promises.push(az(client, i)); 
    return Q.all(promises); 
}).then(function(results) { 
    console.log("everything went right. All results:", results); 
}, function(err) { 
    console.log("something (either getCount, or one of the az calls) blew up", err); 
}); 
+0

我想要做的是如果循環中的任何項目都有問題拋出和異常。推遲,拒絕不正確的方式來做到這一點? – reza

+0

是的,但是你好像錯誤地放置了循環。或者'mgmtISCSIGetTargetList'方法是否一次返回所有的項目,你甚至不需要多次調用它? – Bergi

+0

我錯過了循環。必須。 mgmtISCSIGetTargetList一次返回一個項目 – reza