【问题标题】:How to use javascript promises that waits for jquery ajax to finish before moving onto next promise?如何使用等待 jquery ajax 完成后再进入下一个承诺的 javascript 承诺?
【发布时间】:2017-12-02 00:52:39
【问题描述】:

如何使用等待 jquery ajax 完成后再进入下一个承诺的 javascript 承诺?

 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 阻止了 Promise 的按顺序运行。它应该等到一个 Promise 完成后再进行下一个 Promise。

发生了什么

【问题讨论】:

  • 你需要在ajax成功函数中解析promise,而不是在随机超时之后......
  • 我是 javascript 承诺的新手。我现在看到超时了。如何解决 javascript 承诺?
  • 使用作为参数传递给 Promise 的“resolve”函数。此行resolve(value);
  • 只是打电话给你的决心

标签: javascript jquery ajax es6-promise


【解决方案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);
  });
}

【讨论】:

    【解决方案2】:

    实际上,Promise.all 并不能保证按顺序解决所有的 Promise。 Promise 在创建时开始其任务,Promise.all 只是等待它们解决。 如果您正在寻找一种让他们按顺序解决的方法,您可以使用

    promises.reduce((promise,function) => p.then(function),Promise.resolve());
    

    【讨论】:

      猜你喜欢
      • 2021-05-21
      • 2016-04-25
      • 2016-10-16
      • 2017-06-17
      • 2017-06-24
      • 2020-10-31
      • 2018-08-06
      相关资源
      最近更新 更多