jQuery deferred:

jQuery deferred:

本文关键字:deferred jQuery      更新时间:2023-09-26

我有一个函数。函数内部看起来像:

if (isNewCustomer) {
    doSomething();
    cleanup();
}
else {
    $.getJSON(..., function(result) {
        doSomethingElse();
        cleanup();
    });
}

我希望我可以通过使用deferred来简单地做到这一点。我的尝试看起来像:

var do_it = doSomething;
if (!isNewCustomer) {
    do_it = $.getJSON(..., function(result) {
        doSomethingElse();
    });
}
$.when(do_it).done(function() {
    cleanup();
});

但这不起作用。我做错了什么?

EDIT:将变量do重命名为do_it。这不是代码的问题。问题是当do_itdoSomething时,doSomething不会被执行。

do是javascript中的一个关键字,因此最好重命名变量。

var do_it = doSomething;
if (!isNewCustomer) {
    do_it = $.getJSON(..., function(result) {
        doSomethingElse();
    });
}
//          || << note me
$.when(do_it()).done(function() {
    cleanup();
});
var result;
if (isNewCustomer) {
    result = doSomething();
} else {
    result = $.getJSON( ..., function( data ) {
        doSomethingElse( data );
    });
}
$.when( result ).done(function() {
    cleanup();
});

请参阅上面的代码:您从未像Gigi指出的那样调用过函数。

看看这个jsfiddlehttps://jsfiddle.net/timlint/tg7xqtha/

使用Deferred是一种方法。有时很难理解流程以及如何传递数据,但这个例子可能会给你一些启示。

你几乎可以把延期看作一个标志。在函数中,您可以创建一个延迟对象。

该函数返回被延迟的。promise()。这允许您调用函数doSomething(bool).done(),并在它完成后执行某些操作。当您知道任务已完成,并且在此之前不会调用该任务时,您将解决延迟。

function doSomething(isNewCustomer)
{
// think of a deferred as a flag object in a way
var d = $.Deferred();

if(!isNewCustomer)
{
    $.getJSON(..., function(result) {
        // work with data
    }).done(function() {
        // finisn up data
        // set deferred to resolved
        d.resolve();
    });
}
else
{
    // some business logic
    // set deferred to resolved
    d.resolve();   
}
// returning the promise lets you call .done()
// on this function call in the main call
return d.promise();
}

您需要一个显式的Deferred。如果您传递when()一个不是Deferred的参数,则会立即调用该函数,这可能就是您得到意外结果的原因。

var deferred = $.Deferred();
if (isNewCustomer) {
    deferred.resolveWith(doSomething());
}
else {
    $.getJSON(...).
        done(function(result) {
            deferred.resolveWith(doSomethingElse(result));
        }).
        fail(function(...) {
            deferred.rejectWith(...);
        });
}
deferred.promise().always(function() { cleanup(); });