以角度同步处理循环

Process loop synchronously in angular

本文关键字:处理 循环 同步      更新时间:2023-09-26

我有一个$http请求,它返回了一堆行。我需要同步处理每个结果。我的大脑很难理解Angular。

每个记录都需要根据iOS设备上的本地SQLite数据库进行处理,这是一个异步调用。

如果任何循环记录失败,我需要中止整个操作(和循环)。

下面是代码,看看它是否有帮助。。。

var username = $rootScope.currentUser;
            window.logger.logIt("Executing incremental sync with username " + username);
            var url = $rootScope.serviceBaseUrl + 'SyncData/GetSyncItems?userid=' + username + '&lastSyncDate=' + lastSyncDate.toString();
            var encoded = encoder.encode($CONFIG.serviceAccount);
            $http.defaults.headers.common.Authorization = 'Basic ' + encoded;
            $http({ method: 'Get', url: url })
                .success(function(data, status, headers, config) {
                    var processes = [];
                    for (var i in data) {
                        var params = data[i].Params;
                        var paramsMassaged = params.replaceAll("[", "").replaceAll("]", "").replaceAll(", ", ",").replaceAll("'", "");
                        var paramsArray = paramsMassaged.split(",");
                        var process;
                        if (data[i].TableName === "Tabl1") {
                            window.logger.logIt("setting the process for a Table1 sync item");
                            process = $Table1_DBContext.ExecuteSyncItem(data[i].Query, paramsArray);
                        } else if (data[i].TableName === "Table2") {
                            window.logger.logIt("setting the process for an Table2 sync item");
                            process = $Table2_DBContext.ExecuteSyncItem(data[i].Query, paramsArray);
                        } else {
                            window.logger.logIt("This table is not included in the sync process. You have an outdated version of the application. Table: " + data[i].TableName);
                        }
                        window.logger.logIt("got to here...");
                        processes.push(process);
                    }
                    window.logger.logIt("Finished syncing all " + data.length + " records in the list...");
                    $q.all(processes)
                        .then(function (result) {
                            // Update the LastSyncDate here
                            $DBConfigurations_DBContext.UpdateLastSyncDate(data[i].CreatedDate);
                            alert("finished syncing all records");
                        }, function (result) {
                            alert("an error occurred.");
                        });
                })
                .error(function(data, status, headers, config) {
                    alert("An error occurred retrieving the items that need to be synced.");
                });

表2 ExecuteSyncItem函数:

ExecuteSyncItem: function (script, params) {
    //window.logger.logIt("In the Table2 ExecuteSyncItem function...");
    //$DBService.ExecuteQuery(script, params, null);
    var deferred = $q.defer();
    var data = $DBService.ExecuteQuery(script, params, null);
    if (data) {
        deferred.resolve(data);
    } else {
        deferred.reject(data);
    }
    return deferred.promise;
}

DB服务代码:

ExecuteQuery: function (query, params, success) {
    $rootScope.db.transaction(function (tx) {
        tx.executeSql(query, params, success, onError);
    });
},

更新:在回答Maxim的问题"您是否记录了流程方法"时。以下是我正在做的。。。

ExecuteSyncItem: function (script, params) {
    window.logger.logIt("In the Experiment ExecuteSyncItem function...");
    //$DBService.ExecuteQuery(script, params, null);
    var deferred = $q.defer();
    var data = $DBService.ExecuteQuery(script, params, function () { window.logger.logIt("successCallback"); });
    if (data) {
        window.logger.logIt("success");
        deferred.resolve(data);
    } else {
        window.logger.logIt("fail");
        deferred.reject(data);
    }
    return deferred.promise;
}

"数据"每次都是未定义的。每次都会记录"fail"以及"successCallback"。此外,executeQuery正在工作,并以我期望的方式更新数据。

所以现在,我想这只是一个promise语法的问题。如果ExecuteQuery实际上并没有填充"data"变量,因为它是异步的,我该如何设置deferred.resolve()和deferred_reject?

您正朝的正确方向前进

我会使用$q.all

$q.all([async1(),async2()….])

将多个承诺组合为一个承诺,当所有输入承诺都得到解决时,该承诺就会得到解决。

返回一个promise,该promise将通过值的数组/哈希进行解析,每个值都对应于promise数组/哈希中同一索引/键处的promise如果通过拒绝来解决任何承诺,则生成的承诺将以相同的拒绝值被拒绝

例如:

var processes = [];
processes.push(Process1);
processes.push(Process2);
/* ... */
 $q.all(processes)
            .then(function(result)
            {    
              /* here all above mentioned async calls finished */
 
              $scope.response_1 = result[0];
              $scope.response_2 = result[1]; 
             
            }, function (result) {
              alert("Error: No data returned");
            }); 

在您的示例中,您在循环中运行并调用异步方法(Process1Process2)10次(分别为8次和2次)。为了使用$q.allProcess1Process2必须返回promise。

所以我会这样写:

var Process1 = function(stuff) {
    var deferred = $q.defer();
    var data = $DBService.ExecuteQuery(stuff.query); // This is asynchronous
 
    if (data ) {
      deferred.resolve(data);
       } else {
    deferred.reject(data);
      }
    return deferred.promise;
}