开发者社区> 问答> 正文

jquery的promise该怎么用?

自己在尝试使用jquery的promise对象的时候,出现了这个问题:

var promise1 = someAjax(); //someFunction返回jq的jqxhr对象
var promise2 = promise1.then(function (data) {
    return ajax1(); //返回jq的jqxhr对象
}, function (xhr) {
    return ajax2(); //返回jq的jqxhr对象
});

promise2.then(function (data) {
    // 我要怎么知道
    // 到底是ajax1执行成功了
    // 还是ajax2执行成功了?
}, function (xhr) {
    alert("error");
});

如上代码所示,promise1成功之后,我希望它执行ajax1();promise1失败之后,我希望它执行ajax2()。但是promise2的话,无论是ajax1()成功了还是ajax2()成功了,它都会走到自己的success的分支里对吧。

我要如何区别呢?

展开
收起
小旋风柴进 2016-05-30 09:31:39 2029 0
1 条回答
写回答
取消 提交回答
  • var promise1 = someAjax(); //someFunction返回jq的jqxhr对象
    var promise2 = promise1.then(function (data) {
        return ajax1(); //返回jq的jqxhr对象
        return ajax2(); //返回jq的jqxhr对象
    }, function (xhr) {
        // nothing here
    });
    
    promise2.then(function (data) {
        // ajax1执行成功,
        // 和ajax2执行成功之后,
        // 我如何针对它俩进行不同的操作?
    }, function (xhr) {
        alert("error");
    });

    也就是说,现在我们有两个问题。
    问题一(我原本的问题):我想在执行某个ajax之后,成功的话,执行ajax1,失败的话,执行ajax2,那么如何分别对ajax1和ajax2的后续进行操作?
    问题二(我追加的问题):我想在执行某个ajax之后,成功的话,执行ajax1和ajax2,那么如何分别对ajax1和ajax2的后续进行操作?
    在stackoverflow上面,这个回答给了我启发,是的,使用$.when()和$.Deferred()
    不废话,直接上代码。

    解决问题一:

    // 为每一个ajax请求声明一个变量,并设为Deferred对象
    // 这一步是必须的,而且必须在$.when前面
    // 因为$.when的参数得是一个Deferred对象
    var someAjaxDfd = $.Deferred();
    var ajax1Dfd = $.Deferred();
    var ajax2Dfd = $.Deferred();
    
    // 这是程序主体
    // 首先执行someAjax
    someAjax(someAjaxDfd);
    $.when(someAjaxDfd).then(function (data) {//这里的参数为什么是data,因为在下面的ajax函数中,我把data当成resolve()的参数传过来了
        // someAjax完成之后,如果成功,执行ajax1
        ajax1(ajax1Dfd);
    }, function (xhr) { //这里的参数为什么是xhr,因为在下面的ajax函数中,我把xhr当成reject()的参数传过来了
        // 如果失败,执行ajax2
        var data = {/* some data */};
        ajax2(data, ajax2Dfd);
    });
    
    $.when(ajax1Dfd).then(function (data) {
        // ajax1成功之后执行的命令
    }, function (xhr) {
        // ajax1失败之后执行的命令
    });
    
    $.when(ajax2Dfd).then(function (data) {
        // ajax2成功之后执行的命令
    }, function (xhr) {
        // ajax2失败之后执行的命令
    });
    
    
    // 这里是三个ajax函数声明
    function someAjax(dfd) {
        $.ajax({
            type: "GET",
            url: "/someajaxurl",
            contentType: "application/json",
            dataType: "json",
            success: function (data) {
                dfd.resolve(data);
            },
            error: function (xhr) {
                dfd.reject(xhr);
            }
        });
    }
    
    function ajax1(dfd) {
        $.ajax({
            type: "GET",
            url: "/ajax1url",
            contentType: "application/json",
            dataType: "json",
            success: function (data) {
                dfd.resolve(data);
            },
            error: function (xhr) {
                dfd.reject(xhr);
            }
        });
    }
    
    function ajax2(data, dfd) {
        $.ajax({
            type: "POST",
            url: "/ajax1url",
            contentType: "application/json",
            dataType: "json",
            data: JSON.stringify(data),
            success: function (data) {
                dfd.resolve(data);
            },
            error: function (xhr) {
                dfd.reject(xhr);
            }
        });
    }

    所以我的思路的原理是,首先声明一个Deferred对象,然后把这个对象传入到ajax的函数里。如果success,那么传入的Deferred调用resolve()方法,如果error,那么传入的Deferred调用reject()方法。然后在程序中用$.when()监听这个Deferred对象,成功或失败,执行不同的指令。

    所以解决问题二,和问题一大同小异:

    var someAjaxDfd = $.Deferred();
    var ajax1Dfd = $.Deferred();
    var ajax2Dfd = $.Deferred();
    
    // 这是程序主体
    // 首先执行someAjax
    someAjax(someAjaxDfd);
    $.when(someAjaxDfd).then(function (data) {
        // someAjax完成之后,如果成功,执行ajax1和ajax2
        ajax1(ajax1Dfd);
        var data = {/* some data */};
        ajax2(data, ajax2Dfd);
    }, function (xhr) { 
        // nothing here
    });
    
    $.when(ajax1Dfd).then(function (data) {
        // ajax1成功之后执行的命令
    }, function (xhr) {
        // ajax1失败之后执行的命令
    });
    
    $.when(ajax2Dfd).then(function (data) {
        // ajax2成功之后执行的命令
    }, function (xhr) {
        // ajax2失败之后执行的命令
    });

    另外,如果ajax请求返回的json格式不对,即使status为200,$.ajax()也是会走到error的eventHandler里面的,这个要注意。

    2019-07-17 19:19:01
    赞同 展开评论 打赏
问答分类:
问答标签:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
Javascript异步编程 立即下载
JavaScript异步编程 立即下载
23-Vue.js在前端...1506518547.pdf 立即下载