0

I'm looking for a way to "unbind" jQuery's $.when() after the .done() callback has been executed a single time, analogous to using jQuery's .one() instead of .on() for a single event. The reason why I am using deferred objects instead of events in this circumstance is because I need to wait for multiple asynchronous processes to complete before the callback can be executed.

To go into more detail, I'm working on a backbone application where I have a model and view for each page. The sequence of displaying a new page looks something like this:

  1. view for the incoming page (call it page A) is told to render
  2. $.when() is used by page A to wait for asynchronous processes (3, 4 & 5) to resolve
  3. data for page A is loaded from the server, populating the model
  4. images in page A's model are preloaded
  5. the previous page, page B, finishes closing (animation is complete)
  6. page A is rendered

This works fine in a hypothetical scenario where each page is only visited once by a user. However, pages are obviously subject to repeat visits, which means that when page B is opened and closed again after the user navigates elsewhere on the website, the deferred object related to the completion of it's .close() method is resolved once more, executing the code block of the .done() callback in page A's .render() method, which is not good.

Ideally, the $.when().done() code block would be "unbound" as soon as it is executed once, or in the .close() method of each page, just as many other event listeners are unbound.

I'm not sure if this is even possible, so maybe there as alternative method to achieve what I'm trying to do here? Maybe their is a path that ditches deferreds and listens for multiple events to fire?

Thanks.

4

1 回答 1

0

在内部,jQuery 在其许多方法中使用“回调”队列来管理多个函数(例如事件处理程序)的添加/删除/触发。

这些队列的构造函数公开为$.Callbacks(flags). 可以利用标志“once”、“memory”、“unique”和“stopOnFalse”来控制队列在触发时的详细行为。在这里阅读更多。

我不确定“访问”和“重复访问”的性质是什么,但假设 javascript 状态持续存在,否则你不会有问题。我认为你需要这样的东西:

//First let's assume you have three promises, corresponding to your steps 3,4,5
var promiseA = .....;
var promiseB = .....;
var promiseC = .....;

//Then you need one or more worker functions
function myFunction() {
    //do whatever is necessary when promises A,B,C are all resolved.
}

//Create a Callbacks queue with the 'once' flag
var callbacks = $.Callbacks('once');//'once' ensures the callback list can only be fired once.
callbacks.add(myFunction);
//add further callback functions here if necessary.

//Now the glue that puts it all together.
$.when(promiseA, promiseB, promiseC).done(callbacks.fire);

//Or, if you need to pass any paramters to the callback function:
$.when(promiseA, promiseB, promiseC).done(function() {
    callbacks.fire(...);
});
于 2012-12-26T22:38:11.627 回答