【问题标题】:If I execute a function which makes an asyncronous call, how do I make the rest of the function wait for the call before executing if doing a loop?如果我执行一个进行异步调用的函数,如果执行循环,如何让函数的其余部分在执行之前等待调用?
【发布时间】:2018-01-25 17:42:11
【问题描述】:

我在 angularJS 应用程序中有这样的功能

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)的其余部分并发出警报

'这是在回调完成之前被击中'

然后在它到达函数的末尾之前,它会返回到异步调用并完成执行。

2 个问题: 我的承诺正确吗?
另外如何让 alert('show success') 或 alert('show failure') 等到调用完全完成并返回结果?

【问题讨论】:

    标签: javascript angularjs asynchronous promise


    【解决方案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] 是否无法正常工作。你必须检查我上面展示的结果。

    【讨论】:

    • 所以我想我明白一切,但是,功能(结果)的事情。这个结果和传递承诺是一样的吗?抱歉,仍然学习 javascript 传递东西的想法比 C# 或 Java 不那么明显。结果是否通过了承诺?你说检查承诺是行不通的。
    • 结果是promise中传入的数据。
    • 太棒了。感谢马修提供的重要信息
    • 很高兴为您提供帮助,如果这是您正在寻找的答案,请不要忘记接受/点赞!
    猜你喜欢
    • 2019-12-20
    • 1970-01-01
    • 1970-01-01
    • 2019-12-30
    • 1970-01-01
    • 2021-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多