我在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
永远不会触发
答案 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