Promise for-loop with Ajax requests

感情迁移 提交于 2019-12-11 00:35:32

问题


I'm creating a native JavaScript application which does loads of Ajax calls in the same process at a certain time. Instead of going through a normal for loop and do them all at once, I thought I'd wait for the Ajax call to complete and then do the next one.

With the help of Stackoverflow I've managed to do this like the following:

function ajaxCall(index) {
    return new Promise(function(resolve) {
        // Ajax request {
            resolve();
        // }
   });
}

Promise.resolve(0).then(function loop(i) {
    if (i < length) {
        return ajaxCall(i).thenReturn(i + 1).then(loop);
    }
}).then(function() {
    // for loop complete
});


Promise.prototype.thenReturn = function(value) {
    return this.then(function() {
        return value; 
    });
};

However, this is too slow for me. I want to be able to keep a var which keeps track of how many Ajax calls are currently in the process so that I can limit the amount.

I've tried multiple things, but I keep running into ininite loops or not getting to the desired result.

How can I do multiple, limited by a specific number, async Ajax calls using the Promise for loop?


回答1:


Sounds like you want a version of Promise.all that takes an array of asynchronous functions rather than promises, and a ceiling on the number of simultaneous operations. Something like:

Promise.allFuncs = (funcs, n) => {
  n = Math.min(n, funcs.length);
  var results = [];
  var doFunc = i => funcs[i]().then(result => {
    results[i] = result; // store result at the correct offset
    if (n < funcs.length) {
      return doFunc(n++);
    }
  });
  // start only n simultaneous chains
  return Promise.all(funcs.slice(0, n).map((p, i) => doFunc(i)))
    .then(() => results); // final result
};

// --- Example: ---

var log = msg => div.innerHTML += msg + "<br>";
var wait = ms => new Promise(resolve => setTimeout(resolve, ms));

var example = ['a','b','c','d','e','f'].map(name =>
  () => (log("started "+name),wait(2000).then(() => (log("ended "+ name), name))));
  
Promise.allFuncs(example, 2)
.then(results => log("Results: "+ results))
.catch(log);
<div id="div"></div>


来源:https://stackoverflow.com/questions/36664272/promise-for-loop-with-ajax-requests

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!