异步javascript,承诺链接-函数在解析后未执行

时间:2019-02-25 11:24:42

标签: javascript jquery asynchronous promise

我正在兑现承诺。当我链许诺时,最后一个then块不会执行。所有其他块都被执行,但是在最后一个承诺解决之后,什么也没有发生。有人可以向我解释我错过了什么吗?

var x = 1;
$(document).ready(function() {
  getJobId(token).then(function(rsp) {
    return rsp;
  }).then(function(job_id) {
    looper().then(function(rsp) {
      console.log("app finished : " + rsp); // this block never gets called
    });
  });
});

function getJobId(token) {
  // does an API call that returns a promise
  return $.ajax({
    url: "url"
  });
}

function looper() {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      // if the call is successful
      if (x == 5) {
        resolve(1); // returns the value 1
      } else {
        x++; // we increment the value of the counter
        console.log("not solved yet");
        looper(); // we call the same function again
      }
    }, 5000); // (waits for 5 seconds)
  });
}

1 个答案:

答案 0 :(得分:2)

问题是您永远无法解决正在等待的承诺,即looper返回的第一承诺。

您必须始终解决或拒绝一项承诺,或使其依赖于另一个。在这种情况下,要做的最小更改是通过将后续looper的承诺传递到resolve来使较早的依赖于后一个:

resolve(looper()); // we call the same function again

但这不是我要做的。相反,我自己不会looper自称。我会让它直接处理事情:

function looper() {
  function loop(resolve, reject) {
    setTimeout(function() {
      // if the call is successful
      if (x == 5) {
        resolve(1); // returns the value 1
      } else {
        x++; // we increment the value of the counter
        console.log("not solved yet");
        loop(resolve, reject);
      }
    }, 5000); // (waits for 5 seconds)
  }
  return new Promise(loop);
}

作为一个单独的问题,您不处理故障。这样做很重要。在这种情况下,可能在looper.then处理程序中返回来自ready的promise并添加一个catch

var x = 1;
$(document).ready(function() {
  getJobId(token).then(function(rsp) {
    return rsp;
  }).then(function(job_id) {
    return looper().then(function(rsp) {
      console.log("app finished : " + rsp); // this block never gets called
    });
  }).catch(function(error) {
    // Handle/report error here
  });
});

function getJobId(token) {
  // does an API call that returns a promise
  return $.ajax({
    url: "url"
  });
}

function looper() {
  function loop(resolve, reject) {
    setTimeout(function() {
      // if the call is successful
      if (x == 5) {
        resolve(1); // returns the value 1
      } else {
        x++; // we increment the value of the counter
        console.log("not solved yet");
        loop(resolve, reject);
      }
    }, 5000); // (waits for 5 seconds)
  }
  return new Promise(loop);
}

注释2:由于您使用的是Promise,因此我认为您的目标是现代环境。在这种情况下,您可以考虑使用fetch(返回一个本机承诺),而不是使用$.ajax,后者返回一个与Promise兼容的jQuery jqXHR对象。