2015-10-17 69 views
3

我有一個數組,我需要通過http post請求一個一個地發送數組值到web服務。對於node.js,我使用「async」包來做ex:async.eachSeries做得很好,我怎麼能爲angular.js做同樣的事情,我的正常異步代碼;異步請求到for循環angular.js

//this code sends all queries of array (maybe 5.000 request at same time , it is hard to process for webservice :=)) at same time and wait for all responses. 
//it works but actually for me , responses should wait others at end of loop should work one by one 
//like async.eachSeries module! 

    for (var i = 0; i < myArr.lenght; i++) { 
     (function (i) { 
       var data = { 
        "myQuery": myArr[i].query 
       }; 
       $http.post("/myServiceUrl", data).success(function (result) { 
        console.log(result); 
       }); 
     })(i); 
} 

兩個馬特方式克里斯大號解答正確,你可以調查Chris的約異步同步在for循環的功能理解的答案。

+0

命令是否重要? – Teliren

+1

你可以在瀏覽器中使用'async'軟件包,使用'$ http'。唯一的問題是如果你想用你的結果更新'$ scope',那麼你可能需要使用'$ scope。$ apply'或'$ timeout'(沒有可選的延遲) – Jack

回答

1

您可以使用$q通過將承諾鏈接在一起來創建類似的要求。例如:

var chain = $q.when(); 
angular.forEach(myArr, function(item){ 
    chain = chain.then(function(){ 
     var data = { 
      myQuery: item.query 
     }; 
     return $http.post('/myServiceUrl', data).success(function(result){ 
      console.log(result); 
     }); 
    }); 
}); 

// the final chain object will resolve once all the posts have completed. 
chain.then(function(){ 
    console.log('all done!'); 
}); 

基本上,您只是在前一個完成後才運行下一個承諾。這裏強調的是,每個請求都會根據您的問題等到前一個請求完成。

+0

我試圖使用這個,但我沒有得到任何系統反應,也許它是關於我的angular.js版本是舊的。我應該在「app.controller」中添加「$ q」嗎? –

+1

$ q是角度的承諾庫,從一開始就處於角度。承諾是使用'$ http'的正確方法,而不是您標記爲正確的錯綜複雜的答案。如果你創建一個小提琴,我們可以幫助你。 –

+1

@MattWay當您執行大量順序計算並以順序方式操作數據時需要錯誤處理來提醒用戶提供更多輸入等時,q庫的問題就出現了。這取決於您的用例,並且您的一攬子聲明並不完全根據我在統計計算應用程序中的實施嘗試正確 –

0

如果順序並不重要,它們被送到

var items = [/* your array */]; 
var promises = []; 
angular.forEach(items, function(value, key){ 
    var promise = $http.post("/myServiceUrl", { "myQuery": value.query }); 
    promises.push(promise); 
}); 
return $q.all(promises); 
+0

我相信這會仍然同時發送所有的請求,而不是關於命令。 –

+0

是的,它與我的第一個代碼類似,但thanx –

1

如果我正確理解你的問題。您希望以同步方式運行for循環,以便只有在前一次迭代完成後纔會發生下一次迭代。爲此,您可以使用同步循環/回調。特別是如果訂單很重要。

 var syncLoop = function (iterations, process, exit) { 
      var index = 0, 
       done = false, 
       shouldExit = false; 
      var loop = { 
       next: function() { 
        if (done) { 
         if (shouldExit && exit) { 
          return exit(); // Exit if we're done 
         } 
        } 
        // If we're not finished 
        if (index < iterations) { 
         index++; // Increment our index 
         process(loop); // Run our process, pass in the loop 
         // Otherwise we're done 
        } else { 
         done = true; // Make sure we say we're done 
         if (exit) exit(); // Call the callback on exit 
        } 
       }, 
       iteration: function() { 
        return index - 1; // Return the loop number we're on 
       }, 
       break: function (end) { 
        done = true; // End the loop 
        shouldExit = end; // Passing end as true means we still call the exit callback 
       } 
      }; 
      console.log('running first time'); 
      loop.next(); 
      return loop; 
     } 

爲了您的具體實現:

syncLoop(myArray.length, function (loop) { 
     var index = loop.iteration(); 
     var data = { 
      "myQuery": myArray[index].query 
     }; 
     $http.post("/myServiceUrl", data).success(function (result) { 
      console.log(result); 
      loop.next(); 
     }); 
    }, function() { 
     console.log('done'); 
    }); 

如果你打算做一些與數據一次返回(如執行計算),你可以用這個方法做,因爲你將返回的數據一個特定的順序。

我在我構建的統計計算web應用程序中實現了類似的東西。

編輯:

爲了說明我使用的時候$ q.when我已成立了一個小提琴有問題。希望這將有助於說明我爲什麼按照我的方式做到了這一點。

https://jsfiddle.net/chrislewispac/6atp3w8o/

從馬特的答案使用下面的代碼:

var chain = $q.when(promise.getResult()); 
    angular.forEach(myArr, function (item) { 
     chain = chain.then(function() { 
      $rootScope.status = item; 
      console.log(item); 
     }); 
    }); 

    // the final chain object will resolve once all the posts have completed. 
    chain.then(function() { 
     console.log('all done!'); 
    }); 

這琴是我的解決方案的一個例子:

https://jsfiddle.net/chrislewispac/Lgwteone/3/

的$ Q版進行比較,以我的版。查看控制檯並想象那些交付給用戶界面的用戶在過程中進行用戶干預和/或對順序退貨執行統計操作。

你會發現它不會在控制檯或Matt的回答中的視圖中依次給出數字1,2,3,4等。它'批'的反應,然後返回它們。因此,如果根據步驟2中的響應不執行步驟3,則至少在提供的答案中不存在突破或顯式控制此處的同步操作的方式。這在嘗試執行順序計算和/或允許用戶控制斷點等時提出了重大問題。

現在,我正在挖掘$ q庫和Q庫以查看是否有更多這個問題的優雅解決方案。但是,我的解決方案按照要求工作,並且非常明確,它允許我將該函數放置在服務中,並按照我的意願操作某些用例,因爲我完全理解它在做什麼。對我而言,這比使用庫更重要(至少在我作爲程序員開發的這個階段,我確信在StackOverflow的同一階段還有很多其他人)。

+0

我想我誤解了你的問題? –

+1

它好嗎,每個請求的響應等待海誓山盟這個代碼,謝謝你的大力幫助:),而且,這個答案將是非常有用的其他人。 –

+0

雖然這個答案在技術上有效,但它不是一個很好的解決方案。 –

1
function logResultFromWebService(value) 
{ 
    $http.post("/myServiceUrl", value).success(console.log); 
} 

angular.forEach(myArray, logResultFromWebService);