如何使用等待jquery ajax完成的javascript promises继续下一个承诺?
bookmakers = [
"bet365","skybet","ladbrokes","williamhill","betfred","paddypower","sportingbet","betvictor","unibet","totesport","coral","boylesports","betstars","blacktype","betfair","betway","betbright","32red","10bet","marathonbet","118bet","888sport","stanjames","winner"
];
function doSomethingAsync(value, dabookie) {
return new Promise((resolve) => {
setTimeout(() => {
///////////////////
console.log("get ajax for "+dabookie);
tasking = "";
dataString = "";
$.ajax({
type: "POST",
url: "testscraperules.php?task="+dabookie,
data: dataString,
cache: false,
timeout: 6000,
statusCode: {
404: function() {
//alert("Error 404");
$("."+dabookie+" td").addClass("yellowback");
$("."+dabookie+" .loading").replaceWith("<img src='cross.png' width='24' height='24' />");
},
503: function(){ // Service Unavailable (server access throttling)
$("."+dabookie+" td").addClass("magentaback");
$("."+dabookie+" .loading").replaceWith("<img src='cross.png' width='24' height='24' />");
//alert("Error 504 Gateway Timeout when accessing \n testscraperules.php?task="+dabookie);
},
504: function(){ // Gateway Timeout
$("."+dabookie+" td").addClass("purpleback");
$("."+dabookie+" .loading").replaceWith("<img src='cross.png' width='24' height='24' />");
//alert("Error 504 Gateway Timeout when accessing \n testscraperules.php?task="+dabookie);
}
}, success: function(html){
// alert("bookmaker in success is \n"+dabookie);
var jsonstring = $(html).filter("textarea").val(); //alert(jsonstring);
if(jsonstring == ""){
$("."+dabookie+" td").addClass("amberback");
$("."+dabookie+" .loading").replaceWith("<img src='cross.png' width='24' height='24' />");
}
jsonstring = "{ \""+dabookie+"\": [ "+jsonstring+" ] }"; //for multiple results 6 horses x 25 bookmakers
console.log(jsonstring);
}, error: function(XMLHttpRequest, status, message){
}
});
//////
console.log("Resolvingx " + dabookie);
resolve(value);
}, Math.floor(Math.random() * 1000));
});
}
function test() {
let i;
let promises = [];
console.log(bookmakers.length);
for (i = 0; i < bookmakers.length; ++i) {
promises.push(doSomethingAsync(i, bookmakers[i]));
}
Promise.all(promises)
.then((results) => {
console.log("All done", results);
})
.catch((e) => {
// Handle errors here
});
}
// test();
$(".goscrape").click(function (){
test();
});
从控制台可以看出,ajax阻止了promises按顺序运行。它应该等到一个承诺完成后再转到下一个承诺。
发生了什么
答案 0 :(得分:1)
如果你想确保承诺按顺序运行,你可以用这样的递归做点什么:
function test() {
runPromise(0);
}
function finish(err) {
if (err) console.log(err);
console.log('finished!');
}
function runPromise(index) {
// jump out of loop if there are no more bookmakers
if (index >= bookmakers.length) return finish();
doSomethingAsync(index, bookmakers[index]).then((value) => {
// do something with the value
// ...
// iterate to the next promise
runPromise(index + 1);
}).catch((err) => {
// break out of loop when an error occurs
finish(err);
});
}
答案 1 :(得分:1)
实际上,Promise.all无法保证按顺序解决所有承诺。 Promise在创建时开始执行任务,而Promise.all只是等待他们解决。 如果您正在寻找他们按顺序解决的方法,您可以使用
// this will search for a car in dictionary under any key and find 1st occurance of it
// of it and remove it. If List for the key is empty, it will remove the key as well.
foreach (var k in cars.Keys)
{
bool found = false;
List<string> ls = cars[k]; // get List for key
if (ls.Contains("chevy", StringComparer.InvariantCultureIgnoreCase))
{
// get first occurance of car and remove it if found in list
var car = ls.FirstOrDefault(c => c.Trim().ToLowerInvariant() == "chevy".Trim().ToLowerInvariant());
if (car != null)
{
found = true; //found 1st occurance of car in Dictionary, flag to exit loop
ls.Remove(car);
}
}
// remove key if its List<string> is empty
if (ls.Count == 0)
{
cars.Remove(k);
}
if (found) break;
}