我看过许多使用这种语法的示例,但我看不出我做错了什么。“then”函数在ajax调用返回之前运行。
我也试过使用$ .deferred和其他一些模式无济于事。
有人能看到我错过的东西吗?
我已经调试过,可以在ajax调用返回成功(或错误)数据之前看到在done / then内部进行的调用。
感谢您的帮助。
主要电话:
this.addFirstTask = function(task) {
var totalHours = GetHours();
$.when(totalHours).done(function (data) {
task.TaskHours(data);
self.add(task);
});
};
它正在调用以下ajax函数:
function GetHours() {
$.ajax({
url: "/api/tst/GetMyData",
type: 'GET',
dataType: 'json',
success: function(data) {
return data;
},
error: function(data) {
return 0;
}
});
};
谢谢!
验尸后
除了将回复添加到ajax调用之外,根据其他建议,我删除了成功&来自ajax调用的错误并将addFirstTask更改为:
this.addFirstTask = function(task) {
var totalHours = GetHours();
$.when(totalHours)
.then(function (data) {task.TaskHours(data);})
.done(function () { self.add(task); });
};
如果GetHours成功,我会更新TaskHours值。如果失败了,我就跳过它。我意识到DONE就像.NET的try / catch中的“FINALLY”。因此,不是立即添加任务,然后让我的可观察绑定在值返回时更新它,即使self.add也是异步调用的一部分。
答案 0 :(得分:26)
function GetHours() {
return $.ajax({
...
});
};
$ .ajax()返回一个Promise。 $ .when()接受一个Promises集合,并返回一个在所有输入promise完成时完成的promise .then()是Promise上的一个方法(在这种情况下,是when()创建的包装器Promise),当promise成功解析时,它调用它的第一个函数arg。
所以,你的GetHours需要返回一个Promise,当()可以换行,然后你调用then()。 你实际上可以跳过when()部分,然后在GetHours返回时调用.then。
你没有收到错误,因为.when()也会接受任何旧对象,如果它没有实现Promise接口,它只会将它视为已经完成的Promise。
答案 1 :(得分:7)
这不是OP的问题,但我发生了类似的事情,因为我通过传递一系列承诺错误地调用$ .when(...)。
根据jQuery.when的文档,如果你想等待多个Deferred对象,你必须这样做:
$.when( d1, d2 ).then(....);
这意味着如果阵列中有多个延迟对象,则应使用 apply(...),否则$ .when将无法正常工作。因此,对延迟对象数组的调用如下所示:
$.when.apply(this, arrayOfDeferred).then(....);
这是一个JS小提琴演示这个:
答案 2 :(得分:1)
您需要从GetHours函数返回$ .ajax的结果。