Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在数组的forEach循环中使用promise来填充对象_Javascript_Arrays_Foreach_Promise_Es6 Promise - Fatal编程技术网

Javascript 如何在数组的forEach循环中使用promise来填充对象

Javascript 如何在数组的forEach循环中使用promise来填充对象,javascript,arrays,foreach,promise,es6-promise,Javascript,Arrays,Foreach,Promise,Es6 Promise,我在一个数组上运行一个forEach循环,并进行两个返回承诺的调用,我想填充一个对象,比如说this.options,然后用它做其他事情。现在,如果我使用下面的代码示例并首先进入then函数,我将遇到异步问题 $.when.apply($, someArray.map(function(item) { return $.ajax({...}).then(function(data){...}); })).then(function() { // all ajax calls do

我在一个数组上运行一个forEach循环,并进行两个返回承诺的调用,我想填充一个对象,比如说
this.options
,然后用它做其他事情。现在,如果我使用下面的代码示例并首先进入then函数,我将遇到异步问题

$.when.apply($, someArray.map(function(item) {
    return $.ajax({...}).then(function(data){...});
})).then(function() {
    // all ajax calls done now
});
这是下面的工作代码,但它只适用于数组中的第一个元素,因为我在响应的
中调用结果函数。我想首先对数组的所有元素执行所有的fetch,然后调用结果函数来执行一些操作

array.forEach(function(element) {
    return developer.getResources(element)
        .then((data) = > {
            name = data.items[0];
            return developer.getResourceContent(element, file);
        })
        .then((response) = > {
            fileContent = atob(response.content);
            self.files.push({
                fileName: fileName,
                fileType: fileType,
                content: fileContent
            });
            self.resultingFunction(self.files)
        }).catch ((error) = > {
            console.log('Error: ', error);
        })
});
如何在forEach循环完成后填充
self.files
对象,然后使用files对象调用结果函数

Promise.all()
在这里会有帮助:

var promises = [];

array.forEach(function(element) {
    promises.push(
        developer.getResources(element)
            .then((data) = > {
                name = data.items[0];
                return developer.getResourceContent(element, file);
            })
            .then((response) = > {
                fileContent = atob(response.content);
                self.files.push({
                    fileName: fileName,
                    fileType: fileType,
                    content: fileContent
                });
            }).catch ((error) = > {
                console.log('Error: ', error);
            })
    );
});

Promise.all(promises).then(() => 
    self.resultingFunction(self.files)
);
这将启动对每个项的AJAX调用,在调用完成后将每个调用的结果添加到
self.files
,并在所有调用完成后调用
self.resultingFunction()


编辑:根据Yury Tarabanko的建议进行简化。

上述公认解决方案的一个细微变化就是:

var promises = array.map(function(element) {
      return developer.getResources(element)
          .then((data) = > {
              name = data.items[0];
              return developer.getResourceContent(element, file);
          })
          .then((response) = > {
              fileContent = atob(response.content);
              self.files.push({
                  fileName: fileName,
                  fileType: fileType,
                  content: fileContent
              });
          }).catch ((error) = > {
              console.log('Error: ', error);
          })
});

Promise.all(promises).then(() => 
    self.resultingFunction(self.files)
);

我使用了
Array.map
而不是
Array.forEach
,这意味着我不需要先创建一个空数组,我只需要重新使用现有的数组。

您可能会看到一个很好的提示。这里给出的解决方案使用
Array#reduce()
来避免在执行任何工作之前必须累积所有承诺,而不是使用
Promise.all()

以下代码是对使用承诺同步的简单理解

let numArr = [1,2,3,4,5];
let nums=[];

let promiseList = new Promise(function(resolve,reject){
  setTimeout(()=>{
        numArr.forEach((val)=>{
        nums.push(val);
    });
    resolve(nums);
 },5000)
})


Promise.all([promiseList]).then((arrList)=>{
  arrList.forEach((array)=>{
    console.log("Array return from promiseList object ",array);    
  })

 });

上面的示例将保持arraynums5秒。发布后会在控制台上打印

您可以使用
.map
作为一个周期,为数组的每个元素启动承诺请求,并返回这些承诺的新数组。 我还使用了解构,但不确定这里是否需要它

await Promise.all([...arr.map(i => "our promise func"())]);

当你显然需要
地图时,为什么要
forEach
?@YuryTarabanko我用了一张地图,但那也没用。我在回答中也尝试了这种方法,但使用了
$.when.apply($,promissions).then()
,但也不起作用。我认为它不起作用,因为我没有按照ES6的方式来做。应该是
承诺。所有的
,而不是承诺(复数)。为什么要手动创建承诺?看起来
getResources
已经返回了one@YuryTarabanko出于好奇,如果您将从
getResources
返回的承诺直接推送到
promissions
数组,而不是将其包装在自己的数组中,是否保证在
Promise.all()
的终结处理程序之前先调用所有单个终结处理程序?如果不是,那么创建您自己的承诺似乎是必要的。@TimoSta不是直接从
getResources
获得的,而是您在chain
getResources().then(fn1).then(fn2).catch()中得到的最后一个承诺。每次你打电话给
,你就会得到一个新的承诺。并且确保将在
fn2
之前和终结处理程序之前调用
fn1
。因为承诺会将fn1的结果传递给fn2,然后传递给终结处理程序(作为相应的数组元素)。今天学到了新东西!谢谢:-)您能强调一下您所做的更改吗,这样我们就不必阅读每一行了?我们在结尾添加了一个新的句子来解释我所做的事情。虽然此代码可以回答问题,但提供有关此代码为什么和/或如何回答问题的其他上下文可以提高其长期价值。