如何使用等待jquery ajax完成的javascript promises继续下一个承诺?

时间:2017-12-01 16:30:38

标签: javascript jquery ajax es6-promise

如何使用等待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();
    });

promises not working

从控制台可以看出,ajax阻止了promises按顺序运行。它应该等到一个承诺完成后再转到下一个承诺。

发生了什么

2 个答案:

答案 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;
}