【问题标题】:How to make for loop wait until callback was successful?如何让 for 循环等到回调成功?
【发布时间】:2015-06-15 15:54:47
【问题描述】:
$scope.checkwithfor = function(evlappsub){
        if( evlappsub != "" && typeof evlappsub !="undefined"){
            var s = serviceDomain + '/catanalysisdb/' + evlappsub;
            $http.get(s).success(function(data3){
                $scope.chartscore.name = data3.keyattributes.appName;
                $scope.chartscore.y = (data3.keyattributes.totalAffinity * -1);
                $scope.chartscoreval.push($scope.chartscore);
            });
        }
    }
    var serviceDomain = "url";
    if(evaluation_id !== ''){
         $http.get(serviceDomain + '/catanalysisdb/' + evaluation_id).success(function(data) {
             var evl_id = data.form.mainFields[8].fieldTypeVal;
             for(var i=0;i<evl_id.length;i++){
                 var evljsonsum_ib = evl_id[i].value;
                 evlappsub = "cat_sub_key_val_"+evljsonsum_ib.split("_")[1];
                 $scope.checkwithfor(evlappsub);
             }
         });
    }
  • $scope.chartcoreval.push : 将对象推入数组时,但它只包含最后一个对象。
  • $scope.checkwithfor : 在我得到 get 方法循环的成功结果之前完成。

【问题讨论】:

  • 您不能将同步循环与异步代码一起使用并期望它能够正常工作。发出一个请求,一次发送所有值并让服务器返回一个响应不是更有意义吗?

标签: javascript angularjs http for-loop get


【解决方案1】:

使用承诺

使用 vanilla JavaScript (ECMAScript 5),没有直接的方法可以强制事件循环等待特定的异步调用。但是,如果您确实需要等待异步调用完成然后继续,请使用 Promise

Promise 将集成到 ECMAScript 6

但是有些库可以为您提供 Promise 功能。其中之一是“promisejs”:(您可以选择任何其他的,它们的实现遵循相同的标准。)

https://www.promisejs.org/

另外,你需要调整你的 for 循环

要链接强制异步函数在继续之前完成的承诺,您需要修改您的 for 循环以使此任务成为可能。

$scope.checkwithfor = function(evlappsub){
    return new Promise(function(fulfill,reject){
       if( evlappsub != "" && typeof evlappsub !="undefined"){
           var s = serviceDomain + '/catanalysisdb/' + evlappsub;
           $http.get(s).success(function(data3){
               $scope.chartscore.name = data3.keyattributes.appName;
               $scope.chartscore.y = (data3.keyattributes.totalAffinity * -1);
               $scope.chartscoreval.push($scope.chartscore);
               fulfill(); // SIGNIFY IT'S DONE!
           });
        } 
    });
}
var serviceDomain = "url";
if(evaluation_id !== ''){
     $http.get(serviceDomain + '/catanalysisdb/' + evaluation_id).success(function(data) {
         var evl_id = data.form.mainFields[8].fieldTypeVal;

         // FORMER LOOP ACTION
         function checkEvl(i){
             if (i<evl_id.length){
                 var evljsonsum_ib = evl_id[i].value;
                 evlappsub = "cat_sub_key_val_"+evljsonsum_ib.split("_")[1];
                 $scope.checkwithfor(evlappsub).then(function(){
                     // AFTER FINISH, CALL THE NEXT EVL
                     checkEvl(i+1);
                 });
             }
         }

         checkEvl(0); // STARTS OFF WITH THE FIRST ELEMENT
     });
}

补充说明

您需要用递归函数替换您的 for-loop。 有了这个,你可以在一个 Promise 之后立即重复调用一个函数 通过fulfill() 确认done 信号。

所以流程大致如下所示

checkEvl(0)​​ ⇒ checkwithfor() ⇒ 完成() ⇒ then() ⇒ checkEvl(1) ⇒ ...

【讨论】:

  • 还有其他选项可以用纯 javascript 或 angularjs 实现。
  • Angularjs 也带有承诺。而不是标准的 new Promise(function(fulfill,reject){}) 你可以做 $q(function(fulfill, reject){}) 。看到这个:docs.angularjs.org/api/ng/service/$q
猜你喜欢
  • 2014-05-23
  • 1970-01-01
  • 1970-01-01
  • 2015-11-16
  • 2015-09-10
  • 2017-03-27
  • 2016-07-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多