![](/img/trans.png)
[英]How can i reuse my javascript slider more than once on the same page?
[英]Reuse Deferred more than once
我正在使用延迟,因为我需要异步执行多个进程。
更清楚的是,这是我治疗的意义:
我需要同时调用这两个服务,然后获得两个服务的统一响应,以便根据权限显示链接(我的真正问题是第三个ajax服务,但让我们谈论只有2个来简化)。
首先,我将deferred声明为全局变量:
var treatment1 = $.Deferred();
var treatment2 = $.Deferred();
然后,当我需要完成这项工作时,我将解决方法调用所需的数据,以便在全局唯一处理中使用它:
treatment1.resolve(responseData1)
treatment2.resolve(responseData2)
当treatment1和2完成时,会触发done事件:
$.when(treatment1, treatment2).done(function(responseData1,responseData2) {
DoGlobalTreatmentWithAllResponseData(responseData1,responseData2)
}
我的问题是延期只工作一次。
由于我的网站主要是在ajax中实现的,我需要多次激活该事件。
用户可以单击按钮来搜索用户。 然后显示用户列表,并且异步调用ajax服务。 该操作可以无限重复。
我只需要一种方法来重用延迟但多次的原则。 我知道这个问题已经讨论过了,每个人都说deferred不能这样工作。
但是,是否真的无法重置延迟状态或重置承诺(即使通过使用AOP或其他方式实现自定义解决方案)?
如果不可能,我可以使用什么解决方案? 我不想一个接一个地开火治疗,但我真的想在完成所有治疗后做全局治疗(也就是说,活动中的最后一次治疗结束后),我想使用每个治疗的responseData
服务。
这是我想要自定义的示例代码: http : //jsfiddle.net/PLce6/14/
我希望明确,因为英语不是我的母语。
预先感谢您的帮助。
延迟只能被解决/拒绝一次......但是,我认为问题在于你是如何构建代码的...
只要你每次初始化你的延期,这样做没有任何问题...我认为问题是这样的:
首先,我将deferred声明为全局变量:
var treatment1 =$.Deferred(); var treatment2 = $.Deferred();
相反,您可以尝试在按钮单击中调用的函数中执行此操作
用户可以使用按钮来搜索用户
所以有这样的功能:
function onClick() {
var treatment1 =$.ajax({url: '/call1'});
var treatment2 = $.ajax({url: '/call2'});
$.when(treatment1, treatment2).done(function(obj1, obj2) {
// do whatever else you need
});
}
现在,从您的帖子的其余部分看起来,您正在尝试重用延迟 - 但在这种情况下,您的原始解决方案应该没有将deffered保持为全局的问题,因为您的完成将使用他们解决的任何数据调用。
你可以发布一些代码来帮助解释你正在尝试做什么。
从我自己的评论中更新以进行详细说明
基于op的小提琴,他希望能够多次触发依赖动作。 解决方案是让依赖操作创建新的延迟并将$.when
到自身。 请参阅http://jsfiddle.net/PLce6/15/上的更新小提琴
// global
var d1 = $.Deferred();
var d2 = $.Deferred();
var d3 = $.Deferred();
// here's the reset
function resetDeferreds() {
d1 = $.Deferred();
d2 = $.Deferred();
d3 = $.Deferred();
$.when(d1, d2, d3).done(
function (responseData1, responseData2, responseData3) {
DoGlobalTreatmentWithAllResponseData(responseData1, responseData2, responseData3);
resetDeferreds();
});
// the onclick handlers
function do3() {
d3.resolve('do3 ');
return d3;
}
// the top level $.when
$.when(d1, d2, d3).done(function (responseData1, responseData2, responseData3) {
DoGlobalTreatmentWithAllResponseData(responseData1, responseData2, responseData3);
resetDeferreds();
});
我不明白这是怎么回事。 异步过程应该负责每次都创建一个新的Deferred
对象。
function doSomething() {
var d = $.Deferred();
setTimeout(function () {
d.resolve();
}, 1000);
return d;
}
function doSomethingElse() {
var d = $.Deferred();
setTimeout(function () {
d.resolve();
}, 1000);
return d;
}
然后您可以随时执行以下操作:
$.when(doSomething(), doSomethingElse()).done(function () {
console.log('done');
});
如果你绝对需要能够在同一个Deferred
上多次调用resolve
,那么你应该将Deferred
包装到另一个对象中,让我们说DeferredWrapper
,它将公开与Deferred
相同的API但是会将所有方法调用委托给它的封装Deferred
。
除了委托函数调用之外, DeferredWrapper
还必须跟踪在对象上进行的所有侦听操作(例如,完成,始终,失败...)。 DeferredWrapper
可以将所有操作作为[functionName,arguments]元组存储在内部this._actions
属性中。
最后,您需要为状态更改操作(例如,reject,resolve,resolveWith ...等)提供一个特殊的实现,如下所示:
设d是this._deferred
引用的内部Deferred
。
设fn是被调用函数的函数名。
如果d.state()
未挂起 :
3.1 do d = this._deferred = [[native jQuery Deferred]]
3.2在d
上应用所有操作。
返回d[fn].apply(d, arguments)
注意:您还需要实现自定义promise
实现,并确保其行为正确。 您可以使用类似于所描述的方法。
我要建议一个小小的改变。 您不清楚的一个因素是每次治疗1和治疗2的结果是否不同。 如果他们那么做@raghu和@ juan-garcia
function onClick() {
var treatment1 =$.ajax({url: '/call1'});
var treatment2 = $.ajax({url: '/call2'});
$.when(treatment1, treatment2).done(function(obj1, obj2) {
// do whatever else you need
});
}
如果他们没有改变,那么这样做:
var treatment1 =$.ajax({url: '/call1'});
var treatment2 = $.ajax({url: '/call2'});
function onClick() {
$.when(treatment1, treatment2).done(function(obj1, obj2) {
// do whatever else you need
});
}
或者一些变化。 因为一旦完成,您的回调函数将始终立即执行。 它仍然是异步的,但它不需要等待,因为一切准备就绪。 这适用于两种用例。 这是一种非常常见的数据模式,在页面中绘制新组件时,在功能上非常有用之前可能需要几秒钟才能加载。 这是一个非常有用的延迟加载机制。 一旦它进入,虽然一切看起来好像它瞬间响应。
我在JSFiddle的示例中重新编写了javascript,以显示我认为您需要查看的基础知识。 就在这里 。 举个例子,我认为错误在于相信必须多次调用resolve才能触发行为。 调用完成行为会提示一次性行为,并且每次完成调用都会将新行为加载到队列中。 Resolve被称为一次。 $ .when()。done()你可以调用多次,因为你的行为依赖于特定的when()条件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.