问题 正确等待ajax返回的方法(我不想使用成功处理程序。)[复制]


可能重复:
如何让jQuery执行同步而非异步的AJAX请求?
如何等待ajax调用返回 

听我说。我完全理解这段代码。

$.getJSON(someURL, function(data){
    //do something with my data
})
.success(function () {
    //Call what you want on success
})

如果我只需要采取一个非常静态的动作,这似乎很好。但是,如果我想减少限制,例如这个怎么办?

function my_func(){
    $.getJSON(someURL, function(data){
        //do something with my data... like modify an array or the dom
    })
}

现在是司机

my_func();
//Now I want to call a function that relies on the data that my_func brought into the script.

如果我想这样做,我编写脚本的方式有问题吗?或者我只是错过了一些很棒的内置方法?


2967
2018-03-10 14:55


起源

但这就是成功回调的原因......任何特殊原因导致它不适合你?你需要以什么方式减少限制? - Vincent Ramdhanie
使用 async:false 旗。 - kirilloid
“或者我只是错过了一些很棒的内置方法?”对: api.jquery.com/jQuery.ajax 同 async: false - PeeHaa
您的页面看起来很糟糕并且表现得像锁定一样。知道你为什么要寻找这个“功能”吗? - Kirk Woll
@Jake,让你的调用同步(没有回调)几乎没有例外是一个可怕的想法。你应该断然不要走这条路来“清理你的代码”。 - Kirk Woll


答案:


我看到两种可能的jQuery-ish方式。

第一个是使用可以传递给的另一个回调 my_func

function my_func(callback) {
    $.getJSON(someUrl, function(data) {
        // ...do stuff ...
        if ($.isFunction(callback)) { callback(data); }
    });
}

my_func(function(data) {
    // ..do more stuff..
});

第二种方法是创建一个内部触发的自定义事件 my_func 并且可以从外面听取:

function my_func() {
    $.getJSON(someUrl, function(data) {
        $(document).triggerHandler('my_func:data-received', [data]);
    });
}

$(document).on('my_func:data-received', function(event, data) {
    // ...do stuff...
});

my_func();

我强烈建议使用 async: false 只有在绝对必要的情况下。


另一种(非常简洁的)处理方法是jQuery.Deferred对象:

function my_func() {
    var d = new $.Deferred();
    $.getJSON(someUrl, function(data) {
        d.resolve(data);
    });
    return d;
}

my_func().done(function(data) {
    // ...do stuff...
});

您的函数返回一个允许注册回调的对象。在函数中,您只需要确保调用 resolve 调用所有已注册的 done 回调处理程序。


13
2018-03-10 15:02



递延!我知道我听说过这件事。我想在去年的jquery峰会上听到了关于这个话题的演讲。我应该去找录音。哇噢! - Jake


然后是XHR对象:

var jqXHR = $.getJSON(someURL);

您可以在定义后随处访问它:

jqXHR.always(function() {
    alert('JSON IS COMLETE');
});

jqXHR.done(function(data) {
    //do something with the returned data if success!
});

jqXHR.fail(function(jqXHR, textStatus) {
    alert('JSON FAILED : '+textStatus);
});

小提琴

你甚至可以这样做:

$("#button").on('click', Myfunc);

function Myfunc() {
    var jqXHR = runAjax();
        jqXHR.done(function(data) {
            alert($.parseJSON(data));
            $("#result").html('JSON IS DONE');
        });
}

function runAjax() {
    return $.getJSON(someURL);
}

小提琴


2
2018-03-10 15:41





您可能会将运行数据的函数传递给 my_func()

 //                    v--------receive a callback
function my_func(callback_fn){

    $.getJSON(someURL, callback_fn); // use the callback as the getJSON callback

}

然后...

my_func(function(data) {
    // do something with data
})

...或者如果你想要调用的函数是一个命名函数,那么你当然会按名称传递它...

my_func(someOtherFunction)

无论哪种方式,你的 my_func() 函数将使用它作为回调函数 $.getJSON call,将在数据到达时调用它。


1



你知道这是一个骗局的骗局吗? - PeeHaa
@PeeHaa:好的。几乎所有东西都是骗局。
是的,这就是为什么我们有精确的欺骗选项。 - PeeHaa
@PeeHaa:我们应该关闭StackOverflow (如在当前状态下冻结)。这里有很多信息可以回答99%的问题。事实是,欺骗很少被关闭,所以我放弃了。
@PeeHaa:如果你担心我会辱骂......不要。我不关心代表。如果你能找到一种方法让我轻松地将我的大部分内容转移给你,我很乐意这样做。 (只是想保持足够的规避广告,并能够投票和评论等。)