Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/434.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 等待ajax在下一个ajax调用之前完成_Javascript_Jquery_Ajax_Recursion_Promise - Fatal编程技术网

Javascript 等待ajax在下一个ajax调用之前完成

Javascript 等待ajax在下一个ajax调用之前完成,javascript,jquery,ajax,recursion,promise,Javascript,Jquery,Ajax,Recursion,Promise,在保存列表中的下一个模型之前,我正在尝试等待ajax调用完成保存模型。我在谷歌上搜索,看到了一些关于延迟对象的东西,这些东西对我来说是新的,还有另一个答案,它有一个递归函数。我尝试了递归方法,因为它似乎比延迟对象和使用$.when.apply($,arrayOfAjaxCalls).then()更有意义。因此,该代码(递归代码)如下所示: saveModel(index, numRequests) { var self = this; if (index

在保存列表中的下一个模型之前,我正在尝试等待ajax调用完成保存模型。我在谷歌上搜索,看到了一些关于延迟对象的东西,这些东西对我来说是新的,还有另一个答案,它有一个递归函数。我尝试了递归方法,因为它似乎比延迟对象和使用
$.when.apply($,arrayOfAjaxCalls).then()更有意义。因此,该代码(递归代码)如下所示:

    saveModel(index, numRequests) {
        var self = this;

        if (index < numRequests) {
            var sample = self.samplesToSave[index];    

            return $.ajax({
                url: model.url,
                contentType: "application/json",
                type: "POST",
                data: JSON.stringify(model),
                crossDomain: $.support.cors,
                xhrFields: {
                    withCredentials: $.support.cors,
                },
                success: function(data) {
                    console.log("JUST SAVED");
                    console.log(data);
                },
                error: function(xhr: any) {
                    console.log(xhr);
                },
            }).then(() => {
                self.saveModel(index + 1, numRequests);
            });
        }
    }
由于此代码依赖于其他异步调用的完成,因此我将此新尝试称为:

this.saveContainers(project).then(() => {

}).done(() => {
    self.saveSampleNew();
});

不,它应该是这样工作的。如果您认为它不会等待,请提供更多信息,说明您如何调用它,以及它如何同步递归

但是递归调用有一个缺点:

.then(function() {
  self.saveModel(index + 1, numRequests);
})
然后
以及随后由
saveModel
方法返回的承诺在第一个ajax调用中直接解析,它不会等待递归链。其他ajax调用仍在发生(按预期顺序),但不会被结果承诺跟踪

要获得该承诺,并正确地链接承诺,使其与最后一个(“最里面的”)承诺的结果一致,您需要
将承诺从回调返回
,然后

.then(function() {
  return self.saveModel(index + 1, numRequests);
})

我可能会在这里使用for循环,而不是递归调用——我发现在这个上下文中这些调用更容易阅读

saveModel() {
     var d = $.Deferred(); d.resolve();
     var p = d.promise(); // to start the chain
     this.samplesToSave.forEach(sample => p = p.then(() => makeSaveRequest(sample));
     return p;
}

makeSaveRequest(sample) {
    return $.ajax({...}); // make request using `sample` as data
} 

是吗?如果是,请在你的问题上加上标签。你到底把“下一个saveModel”叫什么?我唯一能看到的是
self.modeldereferred(…)
。请提供一个完整的示例。@Bergi:看起来更像ES6代码。该代码看起来应该能按预期工作。如果您对承诺/延迟对象不熟悉,请查看和。@FelixKling:这就是我问的原因。好吧,从带有块体的ES6 arrow函数中,您需要显式地
返回
。当然,这不会产生太大的影响h在箭头函数中使用
self
而不是
this
,无论使用哪种语言。我尝试过这种方法,但似乎没有达到等待第一个makeSaveRequest完成,然后再为下一个对象调用它的效果。@Crystal那么您可能用错了,可以给我举个例子吗?您确定吗SaveRequest不
返回$.ajax(…
?好的,我更新了底部附近的原始帖子。你能看一下吗?谢谢。好的,我添加了我如何称呼它。如果你还需要所有其他方法,请告诉我。我认为这是更多的域逻辑,可以忽略。@Crystal你没有在任何地方等待它,你是如何实现它的?你需要做
this.saveContainers(project).then(()=>self.saveSampleNew()).done(函数(p){console.log(“保存所有值!”);})
我尝试了这个方法,但它似乎不起作用。它像以前一样按顺序调用saveModel,但实际上并不等待saveModel()第一次完成,然后再调用第二次。
saveModel() {
     var d = $.Deferred(); d.resolve();
     var p = d.promise(); // to start the chain
     this.samplesToSave.forEach(sample => p = p.then(() => makeSaveRequest(sample));
     return p;
}

makeSaveRequest(sample) {
    return $.ajax({...}); // make request using `sample` as data
}