2015-10-17 70 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);