延期不解决

时间:2016-09-21 22:55:19

标签: javascript jquery promise jquery-deferred deferred

我在javascript提交处理程序中有一系列延迟,它们对API进行一系列AJAX调用,直到返回所需的结果。它运作良好,但我做了一个调整,现在我无法弄清楚我哪里出错了,因为新代码似乎有一连串的承诺。

function createLinkAPIJob(type) {
  //code to create a request
  return $.ajax(request)
}

function getJobStatus(jobID) {
  return $.ajax({
    url: Urls['find_job'](jobID),
    contentType: 'application/JSON',
    method: 'GET'
  })
}

// utility function to create a promise that is resolved after a delay
$.promiseDelay = function(t) {
  return $.Deferred(function(def) {
    setTimeout(def.resolve, t);
   }).promise();
 }

function waitForJobStatus(jobID, timeStarted) {
  return $.Deferred(function(def) {

    getJobStatus(jobID).then(function(data) {
      console.log(data);
      var isFinished = data['job']['finished'];
      var jobStatus = 'incomplete';
      var jobStatus = data['job']['job_status'];
      if (isFinished === true) {
        /***** HERE IS THE PROBLEM AREA *****/
        console.log('resolving wait for job status');
        def.resolve(jobStatus);
        //also tried: return jobStatus;
      } else {
        return $.promiseDelay(1000).then(function() {
          return waitForJobStatus(jobID, timeStarted);
        });
      }
    });

  }).promise();
}

function executeLinkAPIJob(type) {
  return $.Deferred(function(def) {

    createLinkAPIJob(type).then(function(response) {
      var jobID = response['data']['job_id'];
      var timeStarted = new Date().getTime() / 1000;
      console.log('waiting for job to finish');
      waitForJobStatus(jobID, timeStarted).then(function(jobStatus) {
        console.log('got job status, updating and resolving');
        // A bunch of code here that doesn't matter for this issue...
        def.resolve();
      });
    });

  }).promise();
} 

// I know this seems stupid in this example, but jobs is sometimes a longer array
jobs = [executeLinkAPIJob(type=type)]
.when.apply($, jobs).then(function() {
  // do something
});

控制台输出为

waiting for job to finish
Object {job: "{"error": "Job not found"}"}
Object {job: Object}
resolving wait for job status

哪个有意义:第一行就在waitForJobStatus被调用之前,然后waitForJobStatus尝试一次并且找不到作业,然后在1秒后再次尝试并找到一个作业,所以它记录data,最后在我解决之前,我添加了一个控制台消息,以证明我们已将其纳入条件。

但是console.log('got job status, updating and resolving');永远不会触发 - waitForJobStatus没有得到解决,我猜,then中的createLinkAPIJob永远不会触发

1 个答案:

答案 0 :(得分:1)

您错误地识别了问题区域。在该i.) swank_template_dp.js:5 Uncaught TypeError: $(...).draggable is not a function(anonymous function) @ swank_template_dp.js:5f @ jquery.combo.min.js?v=4914987:2(anonymous function) ii.)eal_view.jsp?id=61922:830 Uncaught TypeError: $(...).multiselect is not a function(anonymous function) @ deal_view.jsp?id=61922:830j @ jquery.min.js 分支中,延迟解决得很好。问题是if分支:

else

在这里,… else { return $.promiseDelay(1000).then(function() { return waitForJobStatus(jobID, timeStarted); }); } 永远不会解决(也不会被拒绝)!这源于您对deferred antipattern的使用 - 如果您没有使用延迟,def回调return确实会有效。你应该只做这样的链接。如果你正在调用已经返回promises的函数,那么永远不要创建deferred(你已经通过分解then来做得非常好!)

$.promiseDelay