这是我在my previous question遇到的问题的重述,我认为这个问题受到X,Y问题的影响。我希望这个问题更接近我所经历的问题的核心。有关代码,请参阅Github上的scchange.js。
我有一组延迟的jQuery对象,我正在调用$.when
。这些是将POST请求发送到修改数据的服务器的函数。 $.when
调用包含在$.get
回调中。这要求我即将修改的数据字段满足授权要求。这是代码:
$.get('/admin/students/contacts/scchange/phoneTlcForm.html?frn=001' + studentsdcid, function () {
console.log('get callback reached');
$.when.apply($j, phoneAjaxCalls).done(function () {
console.log('phoneAjaxCalls promises resolved');
returnToStudentContacts();
});
});
我正在使用phoneAjaxCalls.push(newPhone(tlcPhone,studentsdcid))
将ajax调用推送到数组,而newPhone返回一个ajax延迟对象:
function newPhone(tlcPhone, studentsdcid) {
//Create new phone
return function() {
return $j.ajax({
type: 'POST',
url: '/admin/changesrecorded.white.html',
data: tlcPhone
});
};
}
运行此代码时,我会在控制台中看到"获得回调"在之前打印" phoneAjaxCalls承诺已解决",这表明请求按照它们在代码中显示的顺序发送。但是,Chrome的DevTools网络标签似乎表明,在加载phoneTlcForm.html
文档之前,phoneAjaxCalls网络请求已完成。
前6个请求都是phoneAjaxCalls
个请求,最后一个请求是来自phoneTlcForm.html
的{{1}},但这应该是第一个!
后端似乎按照网络标签显示的顺序接收这些请求,因为我在对这些$.get
请求的回复中收到了授权错误。
需要发生的事情是phoneAjaxCalls
的请求应在完成任何phoneTlcForm.html
请求之前完成。
我的项目是一个插件,因此我无法修改后端逻辑以简化此过程。在创建或更新数据时,我与之交互的系统具有某些授权要求。后端系统必须"看"在发送修改数据的请求之前,我想要修改的数据字段在HTML页面中呈现。这就是我需要在其他请求之前加载phoneAjaxCalls
页面的原因。
答案 0 :(得分:2)
这里发生的事情是,当您构建phoneAjaxCalls
数组时,您会为每个项目调用$j.ajax
。每次请求都会在您拨打电话时立即发出
我想当你打电话给$j.when.apply($j, phoneAjaxCalls)
时,那里的大部分承诺都已经解决了,并且马上就完成了回调。
让我试着用一些评论来说明:
// previous ajax requests already fired!
$j.get('/admin/students/contacts/scchange/phoneTlcForm.html?frn=001' + studentsdcid, function () {
console.log('get callback reached');
// inspect the state of phoneAjaxCalls here
// they might be resolved already.
// you want to exec those ajax calls here, not before!
$j.when.apply($j, phoneAjaxCalls).done(function () {
console.log('phoneAjaxCalls promises resolved');
returnToStudentContacts();
});
});
所以从这里你有不同的方法来解决它。我认为你已经在question you linked得到了很好的回应。
在每个地方你返回$ j.ajax,你可以返回一个包装它的函数,以避免执行。我们以updateEmail function为例:
return function(){
return $j.ajax({
url: '/ws/schema/table/' + config.contactsEmailTable + '/' + emailRecordId,
data: JSON.stringify(emailUpdateData),
dataType: 'json',
contentType: "application/json; charset=utf-8",
type: 'PUT'
});
};
包装完所有内容后,你可以这样打电话给他们:
$.get('/admin/students/contacts/scchange/phoneTlcForm.html?frn=001' + studentsdcid, function () {
var phoneAjaxCallsPromises = $.map(phoneAjaxCalls, function(c){
return c();
});
$.when.apply($j, phoneAjaxCalls).done(function () {
console.log('phoneAjaxCalls promises resolved');
returnToStudentContacts();
});
});
这个解决方案感觉像是一个黑客,但理解这个问题可能会让你实现正确的解决方案。