如果我执行一个进行异步调用的函数,如果执行循环,如何让函数的其余部分等待调用?

时间:2018-01-25 17:42:11

标签: javascript angularjs asynchronous promise

我在angularJS app中有这样的功能

function Validate() {
    var inputs = $scope.getInput;
    var defer = $q.defer();
    var promises = [];
    _.each(inputs, function(input) {
      promises.push(loadInformation(input)
        .then(function(inputList) {
            repository.calculation(inputList, input);

            if (inputList) {
                return true;
            }
            else {
                return false;
            }
        }));
});
$q.all(promises).then(function() {
    for (var i = 0; i < promises.length; i++) {
        if (!promises[i]) {
            defer.reject();
        }
    }
    defer.resolve(); // after it loops get the answer
});
return defer.promise;
}
function handleAction(event) {
    if (Validate().value) {
        alert('show success');
    }
    else {
        alert('show failue');
    }
    alert('this is being hit before callback finishes');
}

我在handleAction(event)中启动执行,并启动Validate()异步函数。它通过它并且基本上什么都不做,然后它执行handleAction(event)的其余部分并且它发出警报

&#39;这在回调结束之前就已被击中&#39;

然后在它到达函数结束之前,它返回到异步调用并完成执行。

2个问题: 我做的承诺是否正确?
另外,如何提醒(&#39;显示成功&#39;)或提醒(&#39;显示失败&#39;)等待通话完成并返回结果?

1 个答案:

答案 0 :(得分:1)

您只需更改handleAction即可使用promise:

function Validate() {
    var inputs = $scope.getInput;
    var promises = [];
    _.each(inputs, function (input) {
        promises.push(loadInformation(input)
            .then(function (inputList) {
                repository.calculation(inputList, input);

                if (inputList) {
                    return true;
                } else {
                    return false;
                }
            }));
    });
    return $q.all(promises)
        .then(function (results) {
            for(var x = 0; x < results.length; x++){
                if(!results[x]){
                    return $q.reject("Rejected");
                }
            };
            return "Resolved";
        });
}
function handleAction(event) {
    var validatePromise = Validate();
    validatePromise.then(function(data){
        //data === "Resolved"
    }, function(error){
        //error === "Rejected"
    });
}

其他一些值得注意的事项,一旦你做了一些承诺(拒绝/解决),你就不应该再做其中一个,所以我修改了它以做回报。您也可以将数据传递给解析/拒绝。在示例中,我只传入一个字符串。也可以只返回$ q.all而不是创建延迟。同时检查!promise [i]是否因为实际设置而无法工作。你必须检查我在上面展示的结果。