Last Updated: February 25, 2016
·
388
· ktusznio

Memoizing deferreds

Suppose we have the following routes in a front-end app:

/addresses
/checkout

When a user visits /addresses, we pull down their addresses. When they visit /checkout we pull down their addresses, their cart, and their payment methods. The addresses are needed and fetched on both pages.

Here's a nice pattern to ensure the addresses are only fetched once:

class User extends Backbone.Model
  addresses: ->
    unless @dfdAddresses
      addresses = new AddressesCollection
      @dfdAddresses = addresses.fetch()

    @dfdAddresses

Then in the controllers:

# For /addresses
user.addresses().then (addresses) =>
  @render()

# For /checkout
$.when(
  cart.fetch(),
  user.addresses(),
  user.paymentMethods()
).then =>
  @render()

Because the deferred is memoized, the addresses are only fetched once. That saves a request when, for example, the checkout page can direct the user to /addresses to change their shipping address.