2016-04-16 6 views
2

Ich erstelle eine native JavaScript-Anwendung, die zu einem bestimmten Zeitpunkt viele Ajax-Aufrufe in demselben Prozess ausführt. Anstatt eine normale for-Schleife zu durchlaufen und sie alle auf einmal zu tun, dachte ich, ich würde warten, bis der Ajax-Anruf beendet ist und dann den nächsten tun.Promise for-Schleife mit Ajax-Anfragen

Mit Hilfe von Stackoverflow Ich habe es geschafft, dies wie folgt zu tun:

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

jedoch, das ist mir zu langsam. Ich möchte in der Lage sein, eine var zu behalten, die verfolgt, wie viele Ajax-Anrufe derzeit in dem Prozess sind, so dass ich den Betrag begrenzen kann.

Ich habe mehrere Dinge ausprobiert, aber ich laufe immer wieder in endlose Loops oder komme nicht zum gewünschten Ergebnis.

Wie kann ich mehrere, durch eine bestimmte Anzahl, async Ajax Anrufe mit der Promise for-Schleife tun?

Antwort

0

Klingt wie Sie wollen eine Version von Promise.all, die eine Reihe von asynchronen Funktionen statt Versprechungen und eine Obergrenze für die Anzahl der gleichzeitigen Operationen dauert. Etwas wie:

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>