如何使这个异步foreach循环与promise一起工作

How do I make this async foreach loop work with promises?

本文关键字:promise 一起 工作 循环 foreach 何使这 异步      更新时间:2023-09-26

我已经把Promises搞砸了,但我是新手,我只是不知道如何正确地做到这一点。目前,Promise没有意义,因为它不会等到异步$.get完成。

基本上,每个foreach迭代都有自己的$.get函数,我需要将它们全部完成,然后继续到具有"…获取相册"console.log的部分。

$.get(id,function(data) {
    //(there's some code here)
    var getZippyUrls = new Promise(function(resolve) {
            zippyarray.forEach(function(zippy) {
            //(more code)
            $.get(zippy.full, function(data) {
                //^This is the foreach of $.gets
               //(code's here)
            });  
           resolve(zippyarray);
        });
    });
    //This is my failed Promise ->
    getZippyUrls.then(function(response) {
        console.log("WE'RE OUT " + response.length);
        response.foreach(function(d) {
            console.log("Promise"+d.media);
        });
        console.log('eyyyyyy');
    });
    console.log("...gets albumart");
    //Now after the previous stuff is done, move on

在同步代码中,当行结束; 时执行延续

有了承诺,通过.then执行延续。您使用了promise构造函数并立即解决了它,您根本没有等待任何任务。我会把我的工作映射到任务中,然后要么把它们与之联系起来,要么连续地等待它们。

//I'm assuming
zippyarray; // array of Zippy objects
var tasks = zippyarray.map(function(zippy,i){
    return function(){ // return a task on that zippy;
       // basic logic here
       return $.get({
            // ajax request
       }).then(function(data){
            // process data like in your code
            // possibly store later for later use too
            return process(data); // return the processed data;
       });
    }
});

现在我们可以按顺序执行它们:

 var p = tasks[0](); // start the first one
 for(var i = 1; i < tasks.length; i++) p = p.then(tasks[i]);
 p.then(function(result){
       // all available here
 });

或者更好,连续:

$.when.apply(tasks.forEach(function(t){ return t(); })).then(function(results){
     // all done
})

我知道这是一个老问题,但最近情况发生了一些变化。

如果您能很好地使用外部库,Bluebirdpromise库对此有一个很好的实现:promise.eeach.

例如

function helperFunc(zippyarray) {
  return Promise.each(zippyarray, zippy => {
    return someOperationThatReturnAPromise(zippy)
      .then((singleResult) => {
        // do something with the operation result if needed
      })
  }).then((originalArray) => {
    // this happens only after the whole array is processed
    // (result is the original array here)
    return Promise.resolve(originalArray)
  })
}

今天,如果我需要按顺序进行,我会使用async/await:

//I'm assuming I'm inside an `async` function
zippyarray; // array of Zippy objects
for(const task of zippyArray) {
  const result = await $.get({ ... });
  // do stuff with result
}

要跟踪多个get请求,您可以使用以下方式:

var cnt = requestCnt;
function finished(){
    if(--cnt)return;
    // Your code here
}
for(var i = 0; i < requestCnt; ++i){
    $.get('something.htm', {data:data}, function(data){
        finished();
    });
}

当请求得到答复时,您总是调用finished函数。当一切都完成时,完成的函数就完成了工作。