How to use promise in forEach loop of array to pop

2019-01-22 09:09发布

I am running a forEach loop on an array and making two calls which return promises, and I want to populate an object say this.options, and then do other stuff with it. Right now I am running into the async issue if i use the following code sample and i get into the then function first.

$.when.apply($, someArray.map(function(item) {
    return $.ajax({...}).then(function(data){...});
})).then(function() {
    // all ajax calls done now
});

This is working code below, but it only works for the first element in the array, because I call the resulting function in the .then of the response. I want to do all the fetch first for all elements of the array and then call the resulting function to do something.

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);
        })
});

How do i populate the self.files object after the forEach loop is complete, and then call the resulting function with the files object?

4条回答
混吃等死
2楼-- · 2019-01-22 09:25

The following code is simple understanding of sync using Promise.

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);    
  })

 });

Above example will hold array nums for 5 sec. and it will print on console after it release.

查看更多
仙女界的扛把子
3楼-- · 2019-01-22 09:36

Just a slight variation of the accepted solution above would be:

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)
);
查看更多
仙女界的扛把子
4楼-- · 2019-01-22 09:42

You might look at this answer to a similar question for an excellent hint. The solution given there uses Array#reduce() to avoid having to accumulate all of the Promises before doing any of the work rather than using Promise.all().

查看更多
太酷不给撩
5楼-- · 2019-01-22 09:47

Promise.all() will be helpful here:

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)
);

This starts the AJAX call for each of the items, adds the result of each call to self.files once the call is complete and calls self.resultingFunction() after all calls have been completed.

Edit: Simplified based on Yury Tarabanko's suggestions.

查看更多
登录 后发表回答