简体   繁体   English

如何将.when()与包含ajax调用的函数一起使用?

[英]How do I use .when() with a function containing an ajax call?

I've seen .when() and .then() used directly with .ajax calls in jquery to delay the execution of a callback function until the ajax is done. 我已经看到.when().then()直接与jquery中的.ajax调用一起使用,以延迟回调函数的执行,直到ajax完成。 What I'm having trouble with is doing the same for functions that are not ajax calls themselves, but contain an ajax function. 我遇到的麻烦是对不是ajax调用自己但包含ajax函数的函数执行相同操作。 I've got the following chunk of code: 我有以下代码块:

$(function() {

    $('.document').on('click', '.ajax', ajaxFunction);

});

function ajaxFunction(e) {
        e.preventDefault();

        // ajax request
        $.ajax({
            async: true,
            cache: false,
            type: 'post',
            url: '/echo/html/',
            data: {
                html: '<p>This is echoed the response in HTML format</p>',
                delay: 1
            },
            dataType: 'html',
            beforeSend: function() {
                console.log('Fired prior to the request');
            },
            success: function(data) {
                console.log('Fired when the request is successfull');
                $('.document').append(data);
            },
            complete: function() {
                console.log('Fired when the request is complete');
            }


        });

        console.log('hello world!');
    }

function defferedFunction(d){
    $.when(ajaxFunction(e)).then(alert('hi mom!'))
}

My goal was to fire the alert ('hi mom!') when the contents of the ajaxFunction function were complete, ie when the ajax was done and 'hello world!' 我的目标是在ajaxFunction函数的内容完成时(即当完成ajax和“ hello world!”时) ajaxFunction警报(“嗨,妈妈!”)。 had logged to the console. 已登录到控制台。 However, the alert never comes up. 但是,警报永远不会出现。

The problem, so far as I can tell, is that the container function doesn't actually return a promise, and hence the .then() section never fires. 据我所知,问题在于容器函数实际上并未返回promise,因此.then()节从不触发。 How can I modify this code to return a promise when all of the internal code, including the ajax, is finished? 当所有内部代码(包括ajax)完成时,如何修改此代码以返回promise?

I'd prefer to continue using the .when() / .then() pattern rather than manually including a callback in ajaxFunction . 我宁愿继续使用.when() / .then()模式,而不是在ajaxFunction手动包含回调。

A fiddle of the above example is here. 上面例子的小提琴在这里。

You can return a promise 你可以兑现承诺

function ajaxFunction(e) {
        e.preventDefault();

        // ajax request
     return $.ajax({       // return promise  
            async: true,
            cache: false,
            type: 'post',
            url: '/echo/html/',

A couple of things. 有几件事。 Like @pXL stated you need to return the promise. 就像@pXL所说的那样,您需要返回承诺。 Also in your fiddle you need to pass the (d) parameter from your defferedFunction to your ajaxFunction. 同样,在小提琴中,您需要将(d)参数从defferedFunction传递给ajaxFunction。 Finally change your .then to .done(function(a){}); 最后将您的.then更改为.done(function(a){});

http://jsfiddle.net/mq4Sj/5/ http://jsfiddle.net/mq4Sj/5/

$(function() {

    $('.document').on('click', '.ajax', defferedFunction);

});

 function defferedFunction(e){
        $.when(ajaxFunction(e)).done(function(d){
        alert(d); // ->> response from server.
 })
    }

I figured out that I can do this by creating a deferred event for the whole function, a deferred event for the non-ajax behavior that I want to capture, resolving the second deferred event after the non-ajax stuff is done, and then using a $.when() to capture when both the deferred object returned by the ajax call is resolved and when the deferred object I created for the non-ajax stuff is done, and then using a .then() to resolve the deferred object for the whole function. 我发现可以通过为整个函数创建一个延迟事件,为我要捕获的非ajax行为创建一个延迟事件,在完成非ajax填充后解决第二个延迟事件来做到这一点,然后使用$.when()来捕获解析由ajax调用返回的延迟对象以及完成为非ajax东西创建的延迟对象的时间,然后使用.then()解析以下内容:整个功能。

It looks like this, all put together: 看起来像这样,全部放在一起:

$(function() {

    $('.document').on('click', '.ajax', defferedFunction);

});

function ajaxFunction(e) {
        e.preventDefault();

        // ajax request
        var ajaxDeferred = $.ajax({
            async: true,
            cache: false,
            type: 'post',
            url: '/echo/html/',
            data: {
                html: '<p>This is echoed the response in HTML format</p>',
                delay: 1
            },
            dataType: 'html',
            beforeSend: function() {
                console.log('Fired prior to the request')

            },
            success: function(data) {
                console.log('Fired when the request is successfull');
                $('.document').append(data);
            },
            complete: function() {
                console.log('Fired when the request is complete');
            }
        })

        var newDeferred = $.Deferred()

        var timeoutDeferred = $.Deferred()

        setTimeout(function(){
            console.log('hello world!')
            timeoutDeferred.resolve()
        }, 2000)

        $.when(timeoutDeferred, ajaxDeferred).then(function(){
            newDeferred.resolve()
        }
        );


        return newDeferred;
    }

function defferedFunction(e){
    $.when(ajaxFunction(e)).done(function(){alert('all done!')})
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM