我的异步回调处理是否安全实现?(JavaScript的)

Is my asynchronous callback processing implemented safely? (javascript)

提问人:Yossi G. 提问时间:4/5/2019 最后编辑:Yossi G. 更新时间:4/6/2019 访问量:58

问:

我对异步回调的概念并不陌生,但我的大部分经验都是用 C# 编写的。我对javascript很陌生。我担心我在这里所做的事情可能是危险的,我将不胜感激你的建议。

我正在尝试做什么 - 为给定帐户中的所有位置调用 Google Insights API。Google 允许每次通话批量处理 10 个营业地点。由于我事先不知道 Google 帐户将拥有多少个位置,因此我不知道我需要拨打多少个电话才能获取所有信息。每次调用都会生成一个异步回调函数,我不知道这些回调将以什么顺序调用。据我了解,不能保证异步回调将按照与其创建顺序相对应的顺序得到响应。

这是我的基本方法。每次创建回调时,全局计数器都会递增。每次执行回调时,它都会将其 response.data 推送到全局数组中 并递减全局计数器。当计数器降为零时,该回调处理程序知道它是最终回调。然后,它调用处理序列中的下一步,该序列聚合来自全局数组的所有响应数据并批量处理它。

代码如下。该代码在初始临时测试中正常运行,但我想知道我所做的是否真的不受可能由同时执行多个回调引起的竞争条件的影响。我构造的操作是原子的,因此不受竞争条件的影响吗?或者我是否需要重构或显式调用锁定机制才能从异步回调中安全地访问我的全局对象?所有的魔力都发生在——

$http.post(url, postData, configHeaders).
    then(function (response) {

        googleResponses.push(response.data);
        googleRequestsOutstanding--;

        if (googleRequestsOutstanding == 0) {
            $scope.viewInsights();
        }
    });

完整代码如下。我想知道这是否安全。谢谢你的建议!

const googleBatchSize = 10;
var googleRequestsOutstanding = 0;
var googleResponses = [];

$scope.batchGoogleRequests = function (url, configHeaders) {

    googleResponses = [];
    var batchIndex = 0;

    var postData = $scope.getPostData();

    for (var i = 0; i < $scope.locationsList.length; i++) {

        postData.locationNames.push($scope.locationsList[i].name);
        batchIndex++;

        if (batchIndex == googleBatchSize || i == $scope.locationsList.length - 1) {

            googleRequestsOutstanding++;

            $http.post(url, postData, configHeaders).
                then(function (response) {

                    googleResponses.push(response.data);
                    googleRequestsOutstanding--;

                    if (googleRequestsOutstanding == 0) {
                        $scope.viewInsights();
                    }
                });

            postData = $scope.getPostData();
            batchIndex = 0;
        }
    }
}
JavaScript AngularJS 回调

评论

0赞 Yossi G. 4/5/2019
谢谢,我会研究你的建议。顺便说一句 - 全面披露;我是javascript的完全新手。所以技术上的答案是,在你提到这些事情之前,我从未听说过这些事情。;-)我会四处搜索,看看我能找到什么,但您可以指出的任何其他信息或代码示例都将不胜感激!
0赞 Jason Spradlin 4/5/2019
你也可以试试 Promise.all,它允许你给它多个承诺,当它们全部完成时,它就会运行:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/......
0赞 georgeawg 4/5/2019
阅读你错过了承诺的重点。顺序承诺应该被链接起来。并行承诺应与 合并。避免在 promise 方法中使用回调。$q.all.then
0赞 Yossi G. 4/5/2019
@JasonSpradlin - 感谢您的参考。这看起来是处理所有承诺何时完成执行的问题的好方法?不过,我问题的另一部分与承诺并发有关。当其他 promise 可能同时执行时,从一个 promise 访问全局变量(简单变量或数组)本质上是安全的还是不安全的?

答: 暂无答案