如何使用Promise将异步Angular函数的值返回到调用方法?

时间:2014-10-08 11:55:58

标签: javascript angularjs angular-promise

我有一个列表,其中填写了我通过这种方式调用assync函数的循环:

在循环中,我正在调用

  row.SUCCES_RATE_SINCE = $scope.computeSuccessRateSinceStart(row);

已调用的功能

  // Calculate percentage of a whole from since
    $scope.computeSuccessRateSinceStart = function(row) {

        db = window.sqlitePlugin.openDatabase({name:"callplanner"});
        // GET APPT COUNT
        db.transaction(function(tx) {
        tx.executeSql(sqlQuery, [], function(tx,results){
            // init empty array for results
            for (var i=0; i < results.rows.length; i++){
                row = results.rows.item(i);
                //Udpate date for writeout
                //row.DATE = moment(row.DATE).format('ddd DD.M');
                console.log("row APPT count is " + JSON.stringify(row));
                apptCnt = row.APPT_CNT;
                convCnt = row.CONVERS_CNT;
                dailySuccessRateSince = apptCnt / convCnt * 100;
                console.log("Success rate since is " +dailySuccessRateSince);
                // THIS IS NOT WORKING
                return Math.round(dailySuccessRateSince);

            }
            });
        },function (e) {
                console.log("ERROR: " + e.message);
                $ionicLoading.show({
                    template: $translate.instant('ERROR_DATABASE'),
                    duration:1000
                });
        });

    };

问题是计算值总是返回null(返回函数在范围内的值可用之前执行)。

我在Angular中很新,但我发现可以使用 promises 来解决这个问题。有人能给我一个如何正确返回价值的例子吗?

非常感谢您的帮助。

修改

现在已触发调用方法,但我无法将返回值传递给变量,如下所示:

var test = $scope.computeSuccessRateSinceStart(row).then(function(result){
     //ALERT WITH VALUE WORKS FINE
     alert("Result " + result);
     return result;
    });
    // THIS GIVES ME EMPTY ARRAY {}
    alert("Result " + JSON.stringify(test));

1 个答案:

答案 0 :(得分:2)

为什么不让你的方法总是返回一个promise,然后从promise中提取结果?

$scope.computeSuccessRateSinceStart = function(row) {
    var deferred = $q.defer();

    db = window.sqlitePlugin.openDatabase({name:"callplanner"});
    // GET APPT COUNT
    db.transaction(function(tx) {
        tx.executeSql(sqlQuery, [], function(tx,results){
            // init empty array for results
            for (var i=0; i < results.rows.length; i++){
                row = results.rows.item(i);
                //Udpate date for writeout
                //row.DATE = moment(row.DATE).format('ddd DD.M');
                console.log("row APPT count is " + JSON.stringify(row));
                apptCnt = row.APPT_CNT;
                convCnt = row.CONVERS_CNT;
                dailySuccessRateSince = apptCnt / convCnt * 100;
                console.log("Success rate since is " +dailySuccessRateSince);
                // THIS IS NOW WORKING:
                deferred.resolve(Math.round(dailySuccessRateSince));
            }
        });
    }, function(e) {
        console.log("ERROR: " + e.message);
        deferred.reject(e);
    });

    return deferred.promise;
};

用法:

$scope.computeSuccessRateSinceStart(row).then(function(result){
    // THIS GIVES THE VALUE:
    alert("Result " + JSON.stringify(test));
    return result;
}, function(e) 
    $ionicLoading.show({
        template: $translate.instant('ERROR_DATABASE'),
        duration:1000
    });
});