jquery when/then(也就是/ when)不等待

Jul*_*man 14 ajax jquery asynchronous deferred

我看了很多使用这种语法的样本,但我看不出我做错了什么."then"函数在ajax调用返回之前运行.

我也试过使用$ .deferred和其他一些模式无济于事.

有人能看到我错过的东西吗?

我已经调试过,可以在ajax调用返回成功(或错误)数据之前看到在done/then内部进行的调用.

谢谢你的帮助.

主要电话:

this.addFirstTask = function(task) {
    var totalHours = GetHours();
    $.when(totalHours).done(function (data) {
        task.TaskHours(data);
        self.add(task);
    });
};
Run Code Online (Sandbox Code Playgroud)

它调用以下ajax函数:

function GetHours() {
    $.ajax({
        url: "/api/tst/GetMyData",
        type: 'GET',
        dataType: 'json',

        success: function(data) {
           return data;
        },

        error: function(data) {
            return 0;
        }
    });
};
Run Code Online (Sandbox Code Playgroud)

谢谢!

验尸:

除了将返回添加到ajax调用之外,根据其他建议,我从ajax调用中删除了成功和错误,并将addFirstTask更改为:

this.addFirstTask = function(task) {
    var totalHours = GetHours();
    $.when(totalHours)
     .then(function (data) {task.TaskHours(data);})
     .done(function () { self.add(task); });
};
Run Code Online (Sandbox Code Playgroud)

如果GetHours成功,我更新TaskHours值.如果失败了,我就跳过它.我意识到DONE就像.NET的try/catch中的"FINALLY".因此,不是立即添加任务,然后让我的可观察绑定在值返回时更新它,即使self.add也是异步调用的一部分.

小智 26

function GetHours() {
    return $.ajax({
        ...
    });
};
Run Code Online (Sandbox Code Playgroud)

$ .ajax()返回一个Promise.$ .when()接受Promises的集合,并返回一个promise,它在所有输入promises完成时完成.then()是Promise上的一个方法(在这种情况下,是when()创建的包装器Promise),它首先调用它当promise成功解决时,函数arg.

所以,你的GetHours需要返回一个Promise,当()可以换行,然后你调用then().你实际上可以跳过when()部分,然后在GetHours返回时调用.then.

你没有收到错误,因为.when()也会接受任何旧对象,如果它没有实现Promise接口,它只会将它视为已经完成的Promise.

  • @JulieLerman:jQuery承诺就像常规承诺或.Net任务一样工作.假装你正在编写C#代码; `$ .ajax`返回响应的`Task`,`then()`表示`ContinueWith()`.您传递的`success`和`error`回调是旧的,基于非承诺的API的残余; 不要使用它们. (3认同)

kro*_*olk 8

这不是OP的问题,但我发生了类似的事情,这是因为我通过传递一组promises错误地调用$ .when(...).

根据jQuery的文档.如果要等待多个Deferred对象,则必须按此方式进行调用:

$.when( d1, d2 ).then(....);
Run Code Online (Sandbox Code Playgroud)

这意味着如果数组中有多个延迟对象,则应使用apply(...),否则$ .when将无法正常工作.因此,对延迟对象数组的调用如下所示:

$.when.apply(this, arrayOfDeferred).then(....);
Run Code Online (Sandbox Code Playgroud)

这是一个JS小提琴演示这个:

https://jsfiddle.net/Lvo4hrez/11/