Skip to main content

Bug Tracker

Side navigation

#14542 closed feature (notabug)

Opened November 14, 2013 09:26AM UTC

Closed January 23, 2014 05:42PM UTC

Add jQuery.Callbacks.forget

Reported by: simen.brekken@gmail.com Owned by: simen.brekken@gmail.com
Priority: undecided Milestone: None
Component: deferred Version: 1.10.2
Keywords: Cc: jaubourg
Blocked by: Blocking:
Description

This patch adds a new method to jQuery.Callbacks named forget which simply erases any previously fired value when the memory flag is present.

While this is a simple one-line function it's very useful for bullding things like caching upon jQuery.Callbacks

Pull request: https://github.com/jquery/jquery/pull/1429

Attachments (0)
Change History (5)

Changed November 14, 2013 07:40PM UTC by timmywil comment:1

owner: → simen.brekken@gmail.com
status: newpending

Can you elaborate on "caching upon jQuery.Callbacks"? I'm trying to imagine the use case.

Changed November 14, 2013 09:13PM UTC by simen.brekken@gmail.com comment:2

status: pendingnew

Here's an example of a cached service that explains the the use case.

var service = $.Callbacks('memory')

service.fetchGreeting = function(url) {
    return $.get('/hello', function(who) {
        service.fire(who) // World
    })
}

service.fetchGreeting()

// Later I'd like to know who said hello using the last valid greeting.
service.add(function(who) {
  console.log('Hello', who)
})

// Now at some point the data goes stale and isn't valid any more.
// Currently there is no way of clearing the callbacks memory without triggering handlers.
service.add(function(who) {
    console.log('Stale Hello', who, ':(')
})

// With the forget method this becomes trivial.
service.fetchGreeting()

// Data goes stale and is no longer valid.
service.forget()

// This won't run immediately because there's no memory of the last value.
service.add(function() {
  console.log('Fresh Hello', target)
})

service.fetchGreeting()

Changed January 23, 2014 04:25PM UTC by timmywil comment:3

cc: → jaubourg
component: unfileddeferred
status: newopen

@jaubourg What is your suggestion here?

Changed January 23, 2014 05:07PM UTC by jaubourg comment:4

Regarding the use-case: why use Callbacks? Store Deferreds in an internal object and you're good.

function cacheFactory( getter ) {
  var cache = {};
  return {
    get: function( key ) {
      return cache[ key ] || ( cache[ key ] = $.when( getter( key ) ) ); 
    },
    clear: function( key ) {
      delete cache[ key ];
    }
}

// Then later in the program

var fetchCache = cacheFactoy( function( url ) {
  return $.ajax( url ); 
} );

function fetchGreeting() {
  return fetchCache.get( "/hello" );
}

As a general remark, the key problem is that your solution adds a method to the Callbacks instance. Why not have a object that hides the Callbacks instance so that you can change the internal Callbacks instance?

If we add a method like forget then we're breaking the Callbacks contract. A "memory once" Callbacks has to stay "invariant", so to speak, once fired.

Changed January 23, 2014 05:42PM UTC by dmethvin comment:5

resolution: → notabug
status: openclosed

Let's pass on this.