【问题标题】:asynchronous javascript promises call with settimeout带有 settimeout 的异步 javascript 承诺调用
【发布时间】:2019-02-21 13:35:31
【问题描述】:

我正在努力实现以下目标:

我要调用 3 个 API 来检索 DATA:

  • 第一个 API 启动一个用于检索数据的作业并为其返回一个 id
  • 第二个 API 通知我作业的状态(已完成、已取消...),我需要对该 API 执行多次调用,然后才能调用下一个。
  • 第三个 API 是在作业完成时将数据发回给我的 API。

我遇到的问题是使用第二个 API,我没有成功将数据发送回我的程序,这是我的代码:

function getJobId(token) {
  return  $.ajax({
    url:  "url" + token;
  });
}

function getJobStatus(job_id) {
  var url = "url" + job_id;
  return  $.ajax({
    url: url
  });
}

getJobStatus(job_id).then(function(response) {
  if (response.jobrun_status === "QUEUED" || response.jobrun_status === "INPROGRESS") {
    //setTimeout(recursiveJobIdCheck(job_id), 2000);
    recursiveJobIdCheck(job_id);
  } else {
    console.log(response.jobrun_status);
    return response.jobrun_status;
  }
});

我确实尝试在对第二个 API 的每次调用之间设置一个超时,但没有成功,有人可以向我解释如何实现这一点,同时在每次请求调用之间保持间隔直到作业完成。

提前谢谢你。

编辑:我忘了在这里添加 recursiveJobIdCheck 函数

function recursiveJobIdCheck2(job_id) {
  return new Promise((resolve,reject) => {
    getJobStatus(job_id).then(function(response){
      if(response.jobrun_status === "QUEUED" || response.jobrun_status === "INPROGRESS"){
        //setTimeout(recursiveJobIdCheck(job_id), 2000);
        recursiveJobIdCheck2(job_id);
      }
      else{
        if(response.jobrun_status === "COMPLETED"){
        console.log(response.jobrun_status);
         resolve(response.jobrun_status);
         }
         else{
           reject(response.jobrun_status);
         }
      }
    });
  });
}

对 api 的调用在完成之前一直在运行,当我通过 Resolve 函数返回值时,.then 块内的主程序中没有任何反应

【问题讨论】:

  • 您是完全没有得到响应还是出现某种错误?
  • @Amiratak88 没有区别,jQuery ajax 也适用于 Promise。
  • 但没有成功”到底是什么意思?什么有效,什么无效?请贴出recursiveJobIdCheck函数的代码。
  • "我确实尝试过超时" - 你需要将它包装在一个 Promise 中并链接到它。另外不要忘记return所有函数的所有承诺,以便您可以正确等待结果。
  • @Bergi 我知道。只是好奇为什么要使用 jQuery 来处理该语言已经支持的东西。

标签: javascript jquery api asynchronous promise


【解决方案1】:

您将需要async/await 来处理递归 api 调用以简化代码。

function getJobStatus(job_id){
  var url = "url" + job_id;
  return  $.ajax({
    url : url
  });
}

function queueNextCall () {
  return new Promise(function (resolve, reject) {
    setTimeout(resolve, 2000);
  });
}

async function recursiveJobIdCheck(job_id) {
  var response = await getJobStatus(job_id)
  if(response.jobrun_status === "QUEUED" || response.jobrun_status === "INPROGRESS"){
    await queueNextCall();
    return recursiveJobIdCheck(job_id)
  } else {
    console.log(response.jobrun_status);
    return response.jobrun_status;
  }
}

而你所要做的就是打电话

recursiveJobIdCheck(job_id).then(/* Success job function */)

【讨论】:

  • "will need" 有点太强了——尤其是对于递归方法,它可以很容易地用then 语法编写。 await 将允许将其编写为 do…while 循环。
  • 顺便说一句,我推荐给avoid return await。除此之外,这个答案看起来不错!
  • 感谢 Varun 的回答,我想我现在有另一个问题,在解决之后,当我调用函数时,.Then 块没有被执行:我尝试使用 console.log但即使执行已完成,我也看不到任何结果
  • @iliasse,recursiveJobIdCheck(job_id).then(res => console.log(res)) 在控制台打印什么?
  • @varunagarwal 谢谢你的回复,控制台什么都没有显示
猜你喜欢
  • 2017-10-04
  • 1970-01-01
  • 1970-01-01
  • 2020-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-18
  • 2018-04-10
相关资源
最近更新 更多