Search code examples
javascriptjquerypromiselocalforage

Using LocalForage with jQuery's promise library


I use LocalForage for persistent storage in the browser. I also (unfortunately) use jQuery's deferreds and promises everywhere else in the project. I'm trying to use $.when to collect the responses from many LocalForage requests:

var results = _.map(keys, localForage.getItem);
$.when.apply($, results).then(function() {
  // iterate over the arguments object
});

This... doesn't work. I've verified that the results array correctly contains many ES6 promise objects (or shim promises from LocalForage's built in shim, in some browsers). These objects don't have a .promise function on them, so $.when doesn't recognize them as promises, and calls the anonymous then function immediately with all of the promises as arguments. As a test, I tried changing the above code to

var results = _.map(keys, _.constant($.Deferred().resolve(false)));
$.when.apply($, results).then(function() {
  // iterate over the arguments object
});

and it works correctly.

What is the best solution to this? Is there a way to convert the ES6/shim promises into jQuery promises, other than var deferred = $.Deferred(); es6Promise.then(deferred.resolve, deferred.reject)?


Solution

  • What is the best solution to this?

    Don't do it. Don't use $.when.apply. Don't convert ES6 promises to jQuery deferreds.

    ES6 promises are in so many ways better than jQuery deferreds - most importantly, they follow Promises/A+ and are interoperable, making assimilation a non-issue. You can easily use them with jQuery. In your case, it should be

    var results = _.map(keys, localForage.getItem);
    Promise.all(results).then(function(arr) {
      // iterate over arr - no more arguments object!
    });