我什么时候会使用JQuery.Callbacks?

时间:2021-11-02 20:56:42

I was looking through new stuff added to jQuery 1.7 and I saw they now have jQuery.Callbacks() http://api.jquery.com/jQuery.Callbacks/.

我正在查看添加到jQuery 1.7的新内容,我看到他们现在有jQuery.Callbacks()http://api.jquery.com/jQuery.Callbacks/。

The documentation shows you how to use jQuery.callbacks() but not any applicable examples of when I would want to use them.

该文档向您展示了如何使用jQuery.callbacks(),但没有任何适用于我何时想要使用它们的示例。

It seems you can add/remove callbacks from a callbacks list and you can do jQuery.callbacks().fire(args), but this just fires off ALL of the callbacks in that list. Maybe I am missing something but this doesn't seem very useful.

看来你可以在回调列表中添加/删除回调,你可以执行jQuery.callbacks()。fire(args),但这只会触发该列表中的所有回调。也许我错过了一些东西,但这似乎没有用。

In my head when I first saw this new functionality I thought you would be able to use it with key/value pairs. Which would then provide a simple way to manage callback functions in a single place in your application. Something like

在我第一次看到这个新功能时,我认为你可以将它与键/值对一起使用。然后,这将提供一种在应用程序中的单个位置管理回调函数的简单方法。就像是

$.callbacks.add("foo", myFunction);

and then for example if I wanted to call that callback at the end of my function I could do something like

然后例如,如果我想在我的函数结束时调用该回调,我可以做类似的事情

$.callbacks().fire("foo", args);

However it doesn't look like you can fire off specific callbacks, you can only fire off all of them with the given arguments or none of them.

但是,它看起来不像你可以触发特定的回调,你只能使用给定的参数或它们都不会触发所有这些回调。

The closest thing I saw was being given the ability to give the .fire() function a context to set the "this" property

我看到的最接近的事情就是赋予.fire()函数一个上下文来设置“this”属性的能力

.fireWith(context, args)

but this doesn't really help much either.

但这也没有多大帮助。

  1. Am I misunderstanding the documentation?

    我误解了文档吗?

  2. If this is the desired functionality what are some applicable examples where this is useful.

    如果这是所需的功能,那么有用的示例是什么。

6 个解决方案

#1


16  

To expand on @Rockets answer a bit and clear up some confusion:

要扩展@Rockets,请回答一下并澄清一些困惑:

The reason that one might need to use jQuery's $.Callbacks is multifaceted:

人们可能需要使用jQuery的$ .Callbacks的原因是多方面的:

  1. The user has a lot of code in one function and wants to split it up
  2. 用户在一个函数中有很多代码,并希望将其拆分
  3. They take that information and send it through the jQuery callback function which then allows them to have split their code into better manageable pieces with which to work with.
    So (for example) if you look at @Rocket's code:

    他们获取该信息并通过jQuery回调函数发送,然后允许他们将代码拆分为更易于管理的部分。所以(例如)如果你看看@Rocket的代码:

    var clickCallbacks = $.Callbacks();
    
    clickCallbacks.add(function() { //one one function piece
        //parse and do something on the scope of `this`
        var c = parseInt(this.text(), 10);
        this.text(c + 1);
    });
    clickCallbacks.add(function(id) { //add a second non-related function piece
        //do something with the arguments that were passed
        $('span', '#last').text(id);
    });
    
    $('.click').click(function() {
        var $ele = $(this).next('div').find('[id^="clickCount"]');
        clickCallbacks.fireWith($ele, [this.id]); //do two separate but related things.
    });
    
  4. What you can now have is multiple callback batches of function which you can now call whenever you deem it be necessary without the need to make so many changes throughout out your code.
  5. 您现在可以拥有的是多个回调批次的功能,您现在可以在需要时调用它们,而无需在整个代码中进行如此多的更改。

#2


12  

I can see callbacks being useful when you are updating different DOM elements using the same method(s).

当您使用相同的方法更新不同的DOM元素时,我可以看到回调很有用。

Here is a cheesy example: http://jsfiddle.net/UX5Ln/

这是一个俗气的例子:http://jsfiddle.net/UX5Ln/

var clickCallbacks = $.Callbacks();

clickCallbacks.add(function() {
    var c = parseInt(this.text(), 10);
    this.text(c + 1);
});
clickCallbacks.add(function(id) {
    $('span', '#last').text(id);
});

$('.click').click(function() {
    var $ele = $(this).next('div').find('[id^="clickCount"]');
    clickCallbacks.fireWith($ele, [this.id]);
});

It updates the click counter and the 'last clicked' when you click on something.

当您点击某些内容时,它会更新点击计数器和“最后点击”。

#3


7  

An (almost) out of the box jQuery Pub/Sub system

This is IMHO the most interesting application, and since it was not clearly stated in the answers (although some do make allusion to the usage), I am adding it to this relatively old post.

这是恕我直言最有趣的应用程序,因为答案中没有明确说明(虽然有些人暗示了这一点),我将它添加到这个相对较旧的帖子中。

NB: The usage is clearly indicated, with an example, in the jQuery docs, but I guess it was added after the question was posted.

注意:在jQuery文档中有一个例子清楚地表明了用法,但我想这是在问题发布后添加的。

Pub/sub, aka the observer pattern, is a pattern which promotes loose coupling and single responsibility in an application. Rather than having objects calling directly the methods of other objects, objects instead subscribe to a specific task or activity and are notified when it occurs. For a more detailed explanation of the benefits of using the Pub/Sub pattern, you can check Why would one use the Publish/Subscribe pattern (in JS/jQuery)?.

Pub / sub,也就是观察者模式,是一种促进应用程序中松散耦合和单一责任的模式。对象不是让对象直接调用其他对象的方法,而是订阅特定的任务或活动,并在发生时通知。有关使用Pub / Sub模式的好处的更详细说明,您可以检查为什么要使用Publish / Subscribe模式(在JS / jQuery中)?

Sure, this was possible with custom events using trigger, .on() and .off(), but I find jQuery.Callbacks to be a lot more suitable to the task, producing cleaner code.

当然,使用触发器,.on()和.off()的自定义事件是可能的,但我发现jQuery.Callbacks更适合于任务,产生更清晰的代码。

Here is the example snippet from the jQuery documentation:

以下是jQuery文档中的示例代码段:

var topics = {};

jQuery.Topic = function( id ) {
    var callbacks,
        method,
        topic = id && topics[ id ];

    if ( !topic ) {
        callbacks = jQuery.Callbacks();
        topic = {
            publish: callbacks.fire,
            subscribe: callbacks.add,
            unsubscribe: callbacks.remove
        };
        if ( id ) {
            topics[ id ] = topic;
        }
    }
    return topic;
};

And a usage example:

一个用法示例:

// Subscribers
$.Topic( "mailArrived" ).subscribe( fn1 );
$.Topic( "mailArrived" ).subscribe( fn2 );
$.Topic( "mailSent" ).subscribe( fn1 );

// Publisher
$.Topic( "mailArrived" ).publish( "hello world!" );
$.Topic( "mailSent" ).publish( "woo! mail!" );

// Here, "hello world!" gets pushed to fn1 and fn2
// when the "mailArrived" notification is published
// with "woo! mail!" also being pushed to fn1 when
// the "mailSent" notification is published.

/*
output:
hello world!
fn2 says: hello world!
woo! mail!
*/

#4


3  

It seems that $.Callbacks began as an implementation detail: a means to manage lists of functions and to call all the functions in a given list with the same arguments. A little like C#'s multicast delegates, with additional features, like the flags you can pass to customize the list's behavior.

看起来$ .Callbacks开始是一个实现细节:一种管理函数列表并使用相同参数调用给定列表中的所有函数的方法。有点像C#的多播委托,还有其他功能,比如你可以传递的标志来自定义列表的行为。

A good example might be that jQuery uses $.Callbacks internally to implement its ready event. bindReady() initializes a callback list:

一个很好的例子可能是jQuery在内部使用$ .Callbacks来实现它的ready事件。 bindReady()初始化一个回调列表:

readyList = jQuery.Callbacks( "once memory" );

Note the once and memory flags, that ensure the callback list will only be called once, and that functions added after the list has been called will be called immediately.

注意一次和内存标志,确保回调列表只被调用一次,并且在调用列表后添加的函数将立即被调用。

Then, ready() adds the specified handler to that list:

然后,ready()将指定的处理程序添加到该列表:

ready: function( fn ) {
    // Attach the listeners
    jQuery.bindReady();

    // Add the callback
    readyList.add( fn );

    return this;
}

Finally, the callback list is fired when the DOM is ready:

最后,当DOM准备就绪时会触发回调列表:

readyList.fireWith( document, [ jQuery ] );

All the ready handlers are called in the context of the same document with the same reference to the global jQuery object. They can only be called this once, and additional handlers passed to ready() will be called immediately from then on, all of this courtesy of $.Callbacks.

所有就绪处理程序都在同一文档的上下文中调用,并具有对全局jQuery对象的相同引用。它们只能被调用一次,并且从那时起将立即调用传递给ready()的其他处理程序,所有这些都是由$ .Callbacks提供的。

#5


2  

I don't see any specific mention of setting context, but since you can pass an arbitrary number of arguments, that would potentially be useful. You could also make your own convention to pass a flag as a first argument and have listeners return false immediately if they aren't meant to handle the remaining argument list.

我没有看到任何具体提到设置上下文,但由于你可以传递任意数量的参数,这可能是有用的。您还可以使自己的约定将标志作为第一个参数传递,并且如果它们不打算处理剩余的参数列表,则会立即返回false。

I've encountered cases where something like this might have been useful, but have used bind() and trigger() with custom events instead. Imagine some message handling system (a web based chat room or e-mail client) where you're polling a service for new messages. One function might be setting a number in a span or displaying a growl when something happens. Another might be updating a grid. With triggers you would have to trigger the event for each listener and "unroll" the passed arguments from eventData, with callbacks it's just one fire and your listeners are simple javascript functions with a simple argument list.

我遇到过像这样的东西可能有用的情况,但是使用了bind()和trigger()而不是自定义事件。想象一下您正在为新消息轮询服务的一些消息处理系统(基于Web的聊天室或电子邮件客户端)。一个功能可能是在某个范围内设置一个数字,或者在某些事情发生时显示一个咆哮。另一个可能是更新网格。使用触发器,您必须为每个侦听器触发事件​​并从eventData“展开”传递的参数,使用回调它只是一个火,而您的侦听器是带有简单参数列表的简单javascript函数。

Callbacks isn't exactly revolutionary, but it'll make for less and cleaner code.

回调并不完全是革命性的,但它会使代码更少,更清晰。

#6


0  

I'm working on an app with a lot of business logic and at least 11 external services. It really helps keep things straight if you can write your own flow control classes and behaviors using something like Callbacks instead of trying to force your will on the Deferred implementation.

我正在开发一个具有大量业务逻辑和至少11个外部服务的应用程序。如果您可以使用Callbacks之类的东西编写自己的流控制类和行为,而不是试图在Deferred实现上强制您的意愿,那么它确实有助于保持正确。

#1


16  

To expand on @Rockets answer a bit and clear up some confusion:

要扩展@Rockets,请回答一下并澄清一些困惑:

The reason that one might need to use jQuery's $.Callbacks is multifaceted:

人们可能需要使用jQuery的$ .Callbacks的原因是多方面的:

  1. The user has a lot of code in one function and wants to split it up
  2. 用户在一个函数中有很多代码,并希望将其拆分
  3. They take that information and send it through the jQuery callback function which then allows them to have split their code into better manageable pieces with which to work with.
    So (for example) if you look at @Rocket's code:

    他们获取该信息并通过jQuery回调函数发送,然后允许他们将代码拆分为更易于管理的部分。所以(例如)如果你看看@Rocket的代码:

    var clickCallbacks = $.Callbacks();
    
    clickCallbacks.add(function() { //one one function piece
        //parse and do something on the scope of `this`
        var c = parseInt(this.text(), 10);
        this.text(c + 1);
    });
    clickCallbacks.add(function(id) { //add a second non-related function piece
        //do something with the arguments that were passed
        $('span', '#last').text(id);
    });
    
    $('.click').click(function() {
        var $ele = $(this).next('div').find('[id^="clickCount"]');
        clickCallbacks.fireWith($ele, [this.id]); //do two separate but related things.
    });
    
  4. What you can now have is multiple callback batches of function which you can now call whenever you deem it be necessary without the need to make so many changes throughout out your code.
  5. 您现在可以拥有的是多个回调批次的功能,您现在可以在需要时调用它们,而无需在整个代码中进行如此多的更改。

#2


12  

I can see callbacks being useful when you are updating different DOM elements using the same method(s).

当您使用相同的方法更新不同的DOM元素时,我可以看到回调很有用。

Here is a cheesy example: http://jsfiddle.net/UX5Ln/

这是一个俗气的例子:http://jsfiddle.net/UX5Ln/

var clickCallbacks = $.Callbacks();

clickCallbacks.add(function() {
    var c = parseInt(this.text(), 10);
    this.text(c + 1);
});
clickCallbacks.add(function(id) {
    $('span', '#last').text(id);
});

$('.click').click(function() {
    var $ele = $(this).next('div').find('[id^="clickCount"]');
    clickCallbacks.fireWith($ele, [this.id]);
});

It updates the click counter and the 'last clicked' when you click on something.

当您点击某些内容时,它会更新点击计数器和“最后点击”。

#3


7  

An (almost) out of the box jQuery Pub/Sub system

This is IMHO the most interesting application, and since it was not clearly stated in the answers (although some do make allusion to the usage), I am adding it to this relatively old post.

这是恕我直言最有趣的应用程序,因为答案中没有明确说明(虽然有些人暗示了这一点),我将它添加到这个相对较旧的帖子中。

NB: The usage is clearly indicated, with an example, in the jQuery docs, but I guess it was added after the question was posted.

注意:在jQuery文档中有一个例子清楚地表明了用法,但我想这是在问题发布后添加的。

Pub/sub, aka the observer pattern, is a pattern which promotes loose coupling and single responsibility in an application. Rather than having objects calling directly the methods of other objects, objects instead subscribe to a specific task or activity and are notified when it occurs. For a more detailed explanation of the benefits of using the Pub/Sub pattern, you can check Why would one use the Publish/Subscribe pattern (in JS/jQuery)?.

Pub / sub,也就是观察者模式,是一种促进应用程序中松散耦合和单一责任的模式。对象不是让对象直接调用其他对象的方法,而是订阅特定的任务或活动,并在发生时通知。有关使用Pub / Sub模式的好处的更详细说明,您可以检查为什么要使用Publish / Subscribe模式(在JS / jQuery中)?

Sure, this was possible with custom events using trigger, .on() and .off(), but I find jQuery.Callbacks to be a lot more suitable to the task, producing cleaner code.

当然,使用触发器,.on()和.off()的自定义事件是可能的,但我发现jQuery.Callbacks更适合于任务,产生更清晰的代码。

Here is the example snippet from the jQuery documentation:

以下是jQuery文档中的示例代码段:

var topics = {};

jQuery.Topic = function( id ) {
    var callbacks,
        method,
        topic = id && topics[ id ];

    if ( !topic ) {
        callbacks = jQuery.Callbacks();
        topic = {
            publish: callbacks.fire,
            subscribe: callbacks.add,
            unsubscribe: callbacks.remove
        };
        if ( id ) {
            topics[ id ] = topic;
        }
    }
    return topic;
};

And a usage example:

一个用法示例:

// Subscribers
$.Topic( "mailArrived" ).subscribe( fn1 );
$.Topic( "mailArrived" ).subscribe( fn2 );
$.Topic( "mailSent" ).subscribe( fn1 );

// Publisher
$.Topic( "mailArrived" ).publish( "hello world!" );
$.Topic( "mailSent" ).publish( "woo! mail!" );

// Here, "hello world!" gets pushed to fn1 and fn2
// when the "mailArrived" notification is published
// with "woo! mail!" also being pushed to fn1 when
// the "mailSent" notification is published.

/*
output:
hello world!
fn2 says: hello world!
woo! mail!
*/

#4


3  

It seems that $.Callbacks began as an implementation detail: a means to manage lists of functions and to call all the functions in a given list with the same arguments. A little like C#'s multicast delegates, with additional features, like the flags you can pass to customize the list's behavior.

看起来$ .Callbacks开始是一个实现细节:一种管理函数列表并使用相同参数调用给定列表中的所有函数的方法。有点像C#的多播委托,还有其他功能,比如你可以传递的标志来自定义列表的行为。

A good example might be that jQuery uses $.Callbacks internally to implement its ready event. bindReady() initializes a callback list:

一个很好的例子可能是jQuery在内部使用$ .Callbacks来实现它的ready事件。 bindReady()初始化一个回调列表:

readyList = jQuery.Callbacks( "once memory" );

Note the once and memory flags, that ensure the callback list will only be called once, and that functions added after the list has been called will be called immediately.

注意一次和内存标志,确保回调列表只被调用一次,并且在调用列表后添加的函数将立即被调用。

Then, ready() adds the specified handler to that list:

然后,ready()将指定的处理程序添加到该列表:

ready: function( fn ) {
    // Attach the listeners
    jQuery.bindReady();

    // Add the callback
    readyList.add( fn );

    return this;
}

Finally, the callback list is fired when the DOM is ready:

最后,当DOM准备就绪时会触发回调列表:

readyList.fireWith( document, [ jQuery ] );

All the ready handlers are called in the context of the same document with the same reference to the global jQuery object. They can only be called this once, and additional handlers passed to ready() will be called immediately from then on, all of this courtesy of $.Callbacks.

所有就绪处理程序都在同一文档的上下文中调用,并具有对全局jQuery对象的相同引用。它们只能被调用一次,并且从那时起将立即调用传递给ready()的其他处理程序,所有这些都是由$ .Callbacks提供的。

#5


2  

I don't see any specific mention of setting context, but since you can pass an arbitrary number of arguments, that would potentially be useful. You could also make your own convention to pass a flag as a first argument and have listeners return false immediately if they aren't meant to handle the remaining argument list.

我没有看到任何具体提到设置上下文,但由于你可以传递任意数量的参数,这可能是有用的。您还可以使自己的约定将标志作为第一个参数传递,并且如果它们不打算处理剩余的参数列表,则会立即返回false。

I've encountered cases where something like this might have been useful, but have used bind() and trigger() with custom events instead. Imagine some message handling system (a web based chat room or e-mail client) where you're polling a service for new messages. One function might be setting a number in a span or displaying a growl when something happens. Another might be updating a grid. With triggers you would have to trigger the event for each listener and "unroll" the passed arguments from eventData, with callbacks it's just one fire and your listeners are simple javascript functions with a simple argument list.

我遇到过像这样的东西可能有用的情况,但是使用了bind()和trigger()而不是自定义事件。想象一下您正在为新消息轮询服务的一些消息处理系统(基于Web的聊天室或电子邮件客户端)。一个功能可能是在某个范围内设置一个数字,或者在某些事情发生时显示一个咆哮。另一个可能是更新网格。使用触发器,您必须为每个侦听器触发事件​​并从eventData“展开”传递的参数,使用回调它只是一个火,而您的侦听器是带有简单参数列表的简单javascript函数。

Callbacks isn't exactly revolutionary, but it'll make for less and cleaner code.

回调并不完全是革命性的,但它会使代码更少,更清晰。

#6


0  

I'm working on an app with a lot of business logic and at least 11 external services. It really helps keep things straight if you can write your own flow control classes and behaviors using something like Callbacks instead of trying to force your will on the Deferred implementation.

我正在开发一个具有大量业务逻辑和至少11个外部服务的应用程序。如果您可以使用Callbacks之类的东西编写自己的流控制类和行为,而不是试图在Deferred实现上强制您的意愿,那么它确实有助于保持正确。