Javascript 为不同的处理程序向deferred.resolve()传递不同的参数
我正在尝试使用jQuery.Deferrd对象同步多个ajax回调。显然jQuery.when会为您处理这个问题,但是我的代码的架构是,ajax请求不会在同一个方法中被调用。例如,这就是流程: //点击一个按钮 //模块1请求一段html并更新DOM //模块2请求一个不同的html片段并更新DOM 我需要两个模块同时更新DOM,这意味着我需要确保在两个请求都返回后运行回调 模块1和模块2需要能够彼此独立存在,并且彼此不了解,因此不能使用$.when(doMod1Request(),doMod2Request())一起发出请求。然后(function(){…})和回调也应该是独立的 因此,我围绕ajax编写了一个包装器,它将回调添加到延迟对象,并以类似的方式添加到$。当解析延迟对象时,ajax请求返回的次数与延迟对象上的回调次数相同 然而,我的困境被推迟了。resolve()只能用一组参数调用,因此每个回调函数都会得到相同的值 e、 gJavascript 为不同的处理程序向deferred.resolve()传递不同的参数,javascript,jquery,ajax,Javascript,Jquery,Ajax,我正在尝试使用jQuery.Deferrd对象同步多个ajax回调。显然jQuery.when会为您处理这个问题,但是我的代码的架构是,ajax请求不会在同一个方法中被调用。例如,这就是流程: //点击一个按钮 //模块1请求一段html并更新DOM //模块2请求一个不同的html片段并更新DOM 我需要两个模块同时更新DOM,这意味着我需要确保在两个请求都返回后运行回调 模块1和模块2需要能够彼此独立存在,并且彼此不了解,因此不能使用$.when(doMod1Request(),doMod2
var deferred=new$.deferred();
延迟。完成(功能(响应){
console.log(响应);//
});
延迟。完成(功能(响应){
console.log(响应);//
});
延期。决议(“”);
而我想要这样的东西:
var deferred = new $.Deferred();
deferred.done(function (response) {
console.log(response); // <div class="html-snippet-1"></div>
});
deferred.done(function (response) {
console.log(response); // <div class="html-snippet-2"></div>
});
deferred.resolve(['<div class="html-snippet-1"></div>', '<div class="html-snippet-2"></div>']);
$("myButton").on('click', function(){
var snippets = [];
var promises_1 = MODULE_1.getSnippet().done(function(response){
snippets.push({
target: $("#div_1"),
response: response
});
});
var promise_2 = MODULE_2.getSnippet().done(function(response){
snippets.push({
target: $("#div_2"),
response: response
});
});
$.when(promise_1, promise_2).done(function() {
$.each(snippets, function(i, snippetObj) {
snippetObj.target.html(snippetObj.response);
});
});
});
$(function(){
$("myButton").on('click', function(){
var promises = [];
var snippets = [];
var modules = [MODULE_1, MODULE_2, MODULE_3 .....];
for (var i=1; i<=10; i++) {
promises.push(modules[i].getSnippet().done(function(response){
snippets.push({
target: $("#div_" + i),
response: response
};
}));
}
$.when.apply(this, promises).done(function() {
$.each(snippets, function(i, snippetObj) {
snippetObj.target.html(snippetObj.response);
});
});
});
});
var deferred=new$.deferred();
延迟。完成(功能(响应){
console.log(响应);//
});
延迟。完成(功能(响应){
console.log(响应);//
});
延期。决议(['',]);
这是可能的还是我做得不对?让我们假设您的模块看起来像这样:
var MODULE_1 = function() {
function getSnippet() {
return $.ajax({
//ajax options here
});
}
return {
getSnippet: getSnippet
}
}();
var MODULE_2 = function() {
function getSnippet() {
return $.ajax({
//ajax options here
});
}
return {
getSnippet: getSnippet
}
}();
如果模块不同,不要担心,重要的是getSnippet函数每个都返回一个jqXHR对象,该对象(从jQuery1.5开始)实现Promise接口
现在,假设您希望获取这两个代码片段以响应某个事件(例如,单击按钮),并在收到两个ajax响应后执行某些操作,那么单击处理程序将如下所示:
var deferred = new $.Deferred();
deferred.done(function (response) {
console.log(response); // <div class="html-snippet-1"></div>
});
deferred.done(function (response) {
console.log(response); // <div class="html-snippet-2"></div>
});
deferred.resolve(['<div class="html-snippet-1"></div>', '<div class="html-snippet-2"></div>']);
$("myButton").on('click', function(){
var snippets = [];
var promises_1 = MODULE_1.getSnippet().done(function(response){
snippets.push({
target: $("#div_1"),
response: response
});
});
var promise_2 = MODULE_2.getSnippet().done(function(response){
snippets.push({
target: $("#div_2"),
response: response
});
});
$.when(promise_1, promise_2).done(function() {
$.each(snippets, function(i, snippetObj) {
snippetObj.target.html(snippetObj.response);
});
});
});
$(function(){
$("myButton").on('click', function(){
var promises = [];
var snippets = [];
var modules = [MODULE_1, MODULE_2, MODULE_3 .....];
for (var i=1; i<=10; i++) {
promises.push(modules[i].getSnippet().done(function(response){
snippets.push({
target: $("#div_" + i),
response: response
};
}));
}
$.when.apply(this, promises).done(function() {
$.each(snippets, function(i, snippetObj) {
snippetObj.target.html(snippetObj.response);
});
});
});
});
如果您有许多构造类似的模块来获取许多代码段,则会稍微复杂一些,更好一些,如下所示:
var deferred = new $.Deferred();
deferred.done(function (response) {
console.log(response); // <div class="html-snippet-1"></div>
});
deferred.done(function (response) {
console.log(response); // <div class="html-snippet-2"></div>
});
deferred.resolve(['<div class="html-snippet-1"></div>', '<div class="html-snippet-2"></div>']);
$("myButton").on('click', function(){
var snippets = [];
var promises_1 = MODULE_1.getSnippet().done(function(response){
snippets.push({
target: $("#div_1"),
response: response
});
});
var promise_2 = MODULE_2.getSnippet().done(function(response){
snippets.push({
target: $("#div_2"),
response: response
});
});
$.when(promise_1, promise_2).done(function() {
$.each(snippets, function(i, snippetObj) {
snippetObj.target.html(snippetObj.response);
});
});
});
$(function(){
$("myButton").on('click', function(){
var promises = [];
var snippets = [];
var modules = [MODULE_1, MODULE_2, MODULE_3 .....];
for (var i=1; i<=10; i++) {
promises.push(modules[i].getSnippet().done(function(response){
snippets.push({
target: $("#div_" + i),
response: response
};
}));
}
$.when.apply(this, promises).done(function() {
$.each(snippets, function(i, snippetObj) {
snippetObj.target.html(snippetObj.response);
});
});
});
});
$(函数(){
$(“myButton”)。在('单击',函数()上{
var承诺=[];
var片段=[];
var modules=[模_1、模_2、模_3….];
对于(var i=1;i让我们假设您的模块如下所示:
var MODULE_1 = function() {
function getSnippet() {
return $.ajax({
//ajax options here
});
}
return {
getSnippet: getSnippet
}
}();
var MODULE_2 = function() {
function getSnippet() {
return $.ajax({
//ajax options here
});
}
return {
getSnippet: getSnippet
}
}();
如果模块不同,不要担心,重要的是getSnippet函数每个都返回一个jqXHR对象,该对象(从jQuery1.5开始)实现Promise接口
现在,假设您希望获取这两个代码片段以响应某个事件(例如,单击按钮),并在收到两个ajax响应后执行某些操作,那么单击处理程序将如下所示:
var deferred = new $.Deferred();
deferred.done(function (response) {
console.log(response); // <div class="html-snippet-1"></div>
});
deferred.done(function (response) {
console.log(response); // <div class="html-snippet-2"></div>
});
deferred.resolve(['<div class="html-snippet-1"></div>', '<div class="html-snippet-2"></div>']);
$("myButton").on('click', function(){
var snippets = [];
var promises_1 = MODULE_1.getSnippet().done(function(response){
snippets.push({
target: $("#div_1"),
response: response
});
});
var promise_2 = MODULE_2.getSnippet().done(function(response){
snippets.push({
target: $("#div_2"),
response: response
});
});
$.when(promise_1, promise_2).done(function() {
$.each(snippets, function(i, snippetObj) {
snippetObj.target.html(snippetObj.response);
});
});
});
$(function(){
$("myButton").on('click', function(){
var promises = [];
var snippets = [];
var modules = [MODULE_1, MODULE_2, MODULE_3 .....];
for (var i=1; i<=10; i++) {
promises.push(modules[i].getSnippet().done(function(response){
snippets.push({
target: $("#div_" + i),
response: response
};
}));
}
$.when.apply(this, promises).done(function() {
$.each(snippets, function(i, snippetObj) {
snippetObj.target.html(snippetObj.response);
});
});
});
});
如果您有许多构造类似的模块来获取许多代码段,则会稍微复杂一些,更好一些,如下所示:
var deferred = new $.Deferred();
deferred.done(function (response) {
console.log(response); // <div class="html-snippet-1"></div>
});
deferred.done(function (response) {
console.log(response); // <div class="html-snippet-2"></div>
});
deferred.resolve(['<div class="html-snippet-1"></div>', '<div class="html-snippet-2"></div>']);
$("myButton").on('click', function(){
var snippets = [];
var promises_1 = MODULE_1.getSnippet().done(function(response){
snippets.push({
target: $("#div_1"),
response: response
});
});
var promise_2 = MODULE_2.getSnippet().done(function(response){
snippets.push({
target: $("#div_2"),
response: response
});
});
$.when(promise_1, promise_2).done(function() {
$.each(snippets, function(i, snippetObj) {
snippetObj.target.html(snippetObj.response);
});
});
});
$(function(){
$("myButton").on('click', function(){
var promises = [];
var snippets = [];
var modules = [MODULE_1, MODULE_2, MODULE_3 .....];
for (var i=1; i<=10; i++) {
promises.push(modules[i].getSnippet().done(function(response){
snippets.push({
target: $("#div_" + i),
response: response
};
}));
}
$.when.apply(this, promises).done(function() {
$.each(snippets, function(i, snippetObj) {
snippetObj.target.html(snippetObj.response);
});
});
});
});
$(函数(){
$(“myButton”)。在('单击',函数()上{
var承诺=[];
var片段=[];
var modules=[模_1、模_2、模_3….];
对于(var i=1;i我认为这是完全有效的。假设您有独立的模块,您可以这样做(有两个承诺):
现在,如果您想同时执行更新,并且仅当两个请求都成功时,只需编写
$.when(doMod1Request(), doMod2Request()).done(function(mod1result, mod2result) {
doMod1Update(mod1result);
doMod2Update(mod2result);
});
如果使用多个参数调用resolve函数,这只会变得很糟糕,因为jQuery在这方面有点不一致,并且不能真正区分多个参数和一个数组参数
要将它们与您正在使用的发布-订阅模式断开耦合,我建议如下:
function Combination() {
this.deferreds = [];
this.success = [];
this.error = [];
}
Combination.prototype.add = function(def, suc, err) {
this.deffereds.push(def);
this.success.push(suc);
this.error.push(err);
};
Combination.prototype.start = function() {
var that = this;
return $.when.apply($, this.deferreds).always(function() {
for (var i=0; i<that.deferreds.length; i++)
that.deferreds[i].done(that.success[i]).fail(that.error[i]);
// of course we could also call them directly with the arguments[i]
});
};
// Then do
var comb = new Combination();
window.notifyModules("something happened", comb); // get deferreds and handlers
comb.start();
// and in each module
window.listen("something happended", function(c) {
c.add(doRequest(), doUpdate, doErrorHandling);
});
var guid = 0,
deferreds = [];
window.request = function (url, deferred, success) {
var requestId = guid++;
if ($.inArray(deferred) === -1) {
deferreds.push(deferred);
$.extend(deferred, {
requestCount: 0,
responseCount: 0,
args: {}
});
}
deferred.requestCount++;
deferred
.done(function () {
// Corresponding arguments are passed into success callback using requestId
// which is unique to each request.
success.apply(this, deferred.args[requestId]);
});
$.ajax(url, {
success: function () {
// Store arguments on deferrds args obj.
deferred.args[requestId] = arguments;
deferred.responseCount++;
if (deferred.requestCount === deferred.responseCount) {
deferred.resolveWith(this);
}
}
});
};
函数组合(){
这个。延迟=[];
this.success=[];
this.error=[];
}
composition.prototype.add=函数(def、suc、err){
此.deffereds.push(def);
这个。成功。推动(suc);
这个.error.push(err);
};
composition.prototype.start=函数(){
var=这个;
返回$.when.apply($,this.deferreds).always(函数(){
对于(var i=0;i我认为这是完全有效的。假设您有独立的模块,您可以这样做(有两个承诺):
现在,如果您想同时执行更新,并且仅当两个请求都成功时,只需编写
$.when(doMod1Request(), doMod2Request()).done(function(mod1result, mod2result) {
doMod1Update(mod1result);
doMod2Update(mod2result);
});
如果使用多个参数调用resolve函数,这只会变得很糟糕,因为jQuery在这方面有点不一致,并且不能真正区分多个参数和一个数组参数
要将它们与您正在使用的发布-订阅模式断开耦合,我建议如下:
function Combination() {
this.deferreds = [];
this.success = [];
this.error = [];
}
Combination.prototype.add = function(def, suc, err) {
this.deffereds.push(def);
this.success.push(suc);
this.error.push(err);
};
Combination.prototype.start = function() {
var that = this;
return $.when.apply($, this.deferreds).always(function() {
for (var i=0; i<that.deferreds.length; i++)
that.deferreds[i].done(that.success[i]).fail(that.error[i]);
// of course we could also call them directly with the arguments[i]
});
};
// Then do
var comb = new Combination();
window.notifyModules("something happened", comb); // get deferreds and handlers
comb.start();
// and in each module
window.listen("something happended", function(c) {
c.add(doRequest(), doUpdate, doErrorHandling);
});
var guid = 0,
deferreds = [];
window.request = function (url, deferred, success) {
var requestId = guid++;
if ($.inArray(deferred) === -1) {
deferreds.push(deferred);
$.extend(deferred, {
requestCount: 0,
responseCount: 0,
args: {}
});
}
deferred.requestCount++;
deferred
.done(function () {
// Corresponding arguments are passed into success callback using requestId
// which is unique to each request.
success.apply(this, deferred.args[requestId]);
});
$.ajax(url, {
success: function () {
// Store arguments on deferrds args obj.
deferred.args[requestId] = arguments;
deferred.responseCount++;
if (deferred.requestCount === deferred.responseCount) {
deferred.resolveWith(this);
}
}
});
};
函数组合(){
这个。延迟=[];
this.success=[];
this.error=[];
}
composition.prototype.add=函数(def、suc、err){
此.deffereds.push(def);
这个。成功。推动(suc);
这个.error.push(err);
};
composition.prototype.start=函数(){
var=这个;
返回$.when.apply($,this.deferreds).always(函数(){
对于(var i=0;i,为了确保每个回调都传递了相应的参数,我已经执行了以下操作:
function Combination() {
this.deferreds = [];
this.success = [];
this.error = [];
}
Combination.prototype.add = function(def, suc, err) {
this.deffereds.push(def);
this.success.push(suc);
this.error.push(err);
};
Combination.prototype.start = function() {
var that = this;
return $.when.apply($, this.deferreds).always(function() {
for (var i=0; i<that.deferreds.length; i++)
that.deferreds[i].done(that.success[i]).fail(that.error[i]);
// of course we could also call them directly with the arguments[i]
});
};
// Then do
var comb = new Combination();
window.notifyModules("something happened", comb); // get deferreds and handlers
comb.start();
// and in each module
window.listen("something happended", function(c) {
c.add(doRequest(), doUpdate, doErrorHandling);
});
var guid = 0,
deferreds = [];
window.request = function (url, deferred, success) {
var requestId = guid++;
if ($.inArray(deferred) === -1) {
deferreds.push(deferred);
$.extend(deferred, {
requestCount: 0,
responseCount: 0,
args: {}
});
}
deferred.requestCount++;
deferred
.done(function () {
// Corresponding arguments are passed into success callback using requestId
// which is unique to each request.
success.apply(this, deferred.args[requestId]);
});
$.ajax(url, {
success: function () {
// Store arguments on deferrds args obj.
deferred.args[requestId] = arguments;
deferred.responseCount++;
if (deferred.requestCount === deferred.responseCount) {
deferred.resolveWith(this);
}
}
});
};
因此,参数通过闭包进行管理。这使我能够确保两个模块互不了解,并且在另一个模块不存在时不会中断,例如:
var MODULE_1 = function () {
$(".myButton").on('click', function() {
// Cross module communication is achieved through notifications.
// Pass along a new deferred object with notification for use in window.request
window.notify('my-button-clicked', new $.Deferred);
});
}();
var MODULE_2 = function () {
// run get snippet when 'my-button-clicked' notification is fired
window.listen('my-button-clicked', getSnippet);
function getSnippet (deferred) {
window.request('/module2', deferred, function () {
console.log('module2 success');
});
}
}();
var MODULE_3 = function () {
// run get snippet when 'my-button-clicked' notification is fired
window.listen('my-button-clicked', getSnippet);
function getSnippet (deferred) {
window.request('/module3', deferred, function () {
console.log('module3 success');
});
}
}();
以上允许每个模块独立运行,这意味着一个模块将在没有另一个模块的情况下工作,而另一个模块将松散地耦合代码,因为模块2
和模块3
都将相同的延迟对象传递到窗口。请求
两个请求成功返回后,它们将得到解决
这是我的最终实施:
到e