在for循环中运行Dojo xhr.get。执行失序

时间:2014-05-07 14:09:54

标签: javascript for-loop dojo xmlhttprequest

以下函数应该使用一组JSON文件中的load加载到javascript对象中并将它们作为数组返回。从我的调试中我可以看到这一切都正常工作,尽管它在所有其他Javascript完成执行后最后执行load: function(data)

所以函数执行。运行xhr.get 15次。返回currentDataSet(空)。只有这样currentDataSet.push(data);中的load: function(data)才会执行填充currentDataSet。此时由于return已经运行,为时已晚。

require(['dojo/_base/xhr', "dojo/dom", "dojo/date/stamp"], function(xhr, dom){
    generateDataSet = function (startTime) {
        var dataSetFilesNames = generateFilenameSet(startTime);
        var currentDataSet = [];
        for(var j=0; j<15; j++){
            xhr.get({
                url:("/JSONFiles/" + dataSetFilesNames[j]), handleAs:"json",
                load: function(data){
                //The .push statement below is executed 15 times at the end
                    currentDataSet.push(data);
                }
            });
        }
        return currentDataSet;
    }
});

我承认这对我来说是一个全新的领域,我可能会误解xhr.get是如何运作的。我想load函数会在响应从请求中返回时执行。有没有什么方法可以让我获得上面所需的功能,以正确的顺序执行?一种等待每个xhr.get等响应的方法。打开建议。

提前致谢。

1 个答案:

答案 0 :(得分:1)

您可能已经意识到,xhr.get异步发生,这意味着代码将继续执行并注意等待它完成。这就是订单无法预测的原因。

幸运的是,这不是一个新问题,可以使用Promises数组来解决。 Promise接口基本上有一个处理程序,当返回异步结果时,将触发该处理程序,无论调用是否成功。在您的情况下,由于您需要一次处理一个Promise数组,因此可以使用名为all的函数。

all(在dojo / promise / all的情况下)接受一个Promises数组作为输入,并在所有这些都返回结果时执行。这意味着您可以对all使用Promise进行每次调用,等待它们全部完成,然后处理它们。我没有使用dojo/_base/xhr,但我可以提供一个使用dojo/request/xhr的示例,我确信它是相似的:

var promises = [];
for (var j=0; j<15; j++) {
   var promise = xhr(url, {
         handleAs: "json" 
      }).then({
         function(data){
            // process data, return results here 
         }
      });
   promises.push(promise);
} 

all(promises).then(function(results) {
   // process array of all results here
}); 

我已附加了allPromise的链接,因此您可以更多地了解它们。

dojo/promise/all

dojo/promise/Promise