jquery when/then (also when/done) 不等待
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21974649/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
jquery when/then (also when/done) not waiting
提问by Julie Lerman
I've looked at many samples that use this syntax, but I can't see what I"m doing wrong. The "then" function is running before the ajax call returns.
我查看了许多使用这种语法的示例,但我看不出我做错了什么。“then”函数在 ajax 调用返回之前运行。
I've tried also using $.deferred and a few other patterns to no avail.
我也尝试过使用 $.deferred 和其他一些模式无济于事。
Can someone see what I'm missing?
有人可以看到我错过了什么吗?
I have debugged and can see the calls being made from inside the done/then before the ajax call returns it's success (or error) data.
我已经调试并且可以看到在 ajax 调用返回它的成功(或错误)数据之前从 done/then 内部进行的调用。
Thanks for any help.
谢谢你的帮助。
Main call:
主要调用:
this.addFirstTask = function(task) {
var totalHours = GetHours();
$.when(totalHours).done(function (data) {
task.TaskHours(data);
self.add(task);
});
};
It is calling the following ajax function:
它正在调用以下 ajax 函数:
function GetHours() {
$.ajax({
url: "/api/tst/GetMyData",
type: 'GET',
dataType: 'json',
success: function(data) {
return data;
},
error: function(data) {
return 0;
}
});
};
Thanks!
谢谢!
post mortem:
验尸:
in addition to adding the return to the ajax call, as per additional advice, I removed success & error from the ajax call and changed addFirstTask to:
除了将返回添加到 ajax 调用之外,根据其他建议,我从 ajax 调用中删除了成功和错误,并将 addFirstTask 更改为:
this.addFirstTask = function(task) {
var totalHours = GetHours();
$.when(totalHours)
.then(function (data) {task.TaskHours(data);})
.done(function () { self.add(task); });
};
If GetHours succeeds, I update the TaskHours value. If it fails, I just skip it. I realized that DONE is like a "FINALLY" in .NET's try/catch. So rather than adding the task right away and then letting my observable binding update it when the value comes back, even the self.add is part of the asynchronous call.
如果 GetHours 成功,我会更新 TaskHours 值。如果失败,我就跳过它。我意识到 DONE 就像 .NET 的 try/catch 中的“最终”。因此,与其立即添加任务,然后让我的可观察绑定在值返回时更新它,甚至 self.add 也是异步调用的一部分。
回答by Andy Smith
function GetHours() {
return $.ajax({
...
});
};
$.ajax() returns a Promise. $.when() takes a collection of Promises, and returns a promise that completes when all the input promises complete .then() is a method on Promise (in this case, the wrapper Promise that when() created) that calls it's first function arg when the promise resolves with success.
$.ajax() 返回一个 Promise。$.when() 接受一个 Promises 集合,并返回一个在所有输入承诺完成时完成的承诺 .then() 是 Promise 上的一个方法(在这种情况下,是 when() 创建的包装 Promise),它首先调用它当承诺成功解决时,函数 arg。
so, your GetHours needs to return a Promise that when() can wrap, and you call the then() on. you could actually skip the when() part and just call .then on the return from GetHours.
因此,您的 GetHours 需要返回一个 when() 可以包装的 Promise,然后您调用 then()。您实际上可以跳过 when() 部分,只需在从 GetHours 返回时调用 .then。
you aren't getting an error because .when() also takes any old object, and if it doesn't implement the Promise interface, it just treats it like an already-completed Promise.
你不会收到错误,因为 .when() 也接受任何旧对象,如果它没有实现 Promise 接口,它只是把它当作一个已经完成的 Promise。
回答by kroolk
This is not be the OPs issue, but I had something similar happen and it was because I was calling $.when(...) incorrectly by passing an array of promises.
这不是 OP 的问题,但我发生了类似的事情,这是因为我通过传递一组 promise 错误地调用了 $.when(...)。
Per the documentation for jQuery.whenif you want to wait for multiple Deferred objects you must make the call as such:
根据jQuery.when的文档,如果你想等待多个 Deferred 对象,你必须这样调用:
$.when( d1, d2 ).then(....);
That means that if you have multiple deferred objects in an array you should use apply(...), otherwise $.when will not work properly. So your call for an array of deferred objects would look like this:
这意味着如果数组中有多个延迟对象,则应使用apply(...),否则 $.when 将无法正常工作。因此,您对延迟对象数组的调用将如下所示:
$.when.apply(this, arrayOfDeferred).then(....);
Here is a JS Fiddle demonstrating this:
这是一个 JS Fiddle 演示:
回答by Adam
You need to return the result of $.ajax from the GetHours function - like this:
您需要从 GetHours 函数返回 $.ajax 的结果 - 像这样:
function GetHours() {
$.ajax({
url: "/api/tst/GetMyData",
type: 'GET',
dataType: 'json',
success: function(data) {
return data;
},
error: function(data) {
return 0;
}
});
};
};