Skip to content

Instantly share code, notes, and snippets.

@RebootJeff
Last active September 27, 2018 16:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RebootJeff/a581d66557138b95e34f to your computer and use it in GitHub Desktop.
Save RebootJeff/a581d66557138b95e34f to your computer and use it in GitHub Desktop.
Examples of common patterns for promises in JS
// =============================================================================
// Example for unit testing an async func that doesn't already support promises
var Q = require('q'); // You must do `npm install q` first
// Async function that uses callbacks instead of promises
function authenticate(dataToSubmit, callback) {
// blah blah blah
}
// The unit test code...
describe('authentication', function() {
// For some testing frameworks like Jasmine, be sure to include the `done`
// callback (this is not needed when using Jasmine with Karma for AngularJS)
it('should provide user data', function(done) {
// Make a promise from scratch
var deferred = Q.defer();
var promise = deferred.promise;
authenticate(someData, function(userData) {
deferred.resolve(userData);
});
// This `then` pattern doesn't seem more useful than ordinary callbacks
// in this example, but imagine how useful it would be if you were to
// replace several nested callbacks with a flat promise chain.
promise.then(function(userData) {
expect(userData).toBe(xyz);
done();
});
});
});
// =============================================================================
// Another style: Wrap non-promise async functions in your own promise-enabled functions
function authenticateWithPromise(dataToSubmit) {
var deferred = Q.defer();
authenticate(dataToSubmit, function(userData) {
deferred.resolve(userData);
});
return deferred.promise;
}
authenticateWithPromise(someData).then(function(userData) {
// do stuff after `authenciate()` has finished (aka after it has "resolved" the promise);
});
// =============================================================================
// Example of chaining promises...
function foo(input) { /* ... */ } // Pretend all these functions do somtething async & return a promise
function bar(input) { /* ... */ } // bar depends on input that is defined by the result of foo
function baz(input) { /* ... */ } // baz depends on input that is defined by the result of bar
function runPromiseChain(inputForFoo) {
var fooOutput;
var barOutput;
var bazOutput;
return foo(inputForFoo).then(function(result) {
fooOutput = result;
return bar(fooOutput);
}).then(function(result) {
barOutput = result;
return baz(barOutput);
}).then(function(result) {
bazOutput = result;
return {
fooStuff: fooOutput,
barStuff: barOutput,
bazStuff: bazOutput
};
});
}
runPromiseChain(someInput).then(function(result) {
// do stuff with result.fooStuff, result.barStuff, and result.bazStuff
}, function(err) {
// handle errors
console.log('Promise chain rejected because:', err);
});
// =============================================================================
// Example of spreading promises...
function foo() { /* ... */ } // Pretend all these functions do somtething async
function bar() { /* ... */ } // and return a promise. Also, assume they can run
function baz() { /* ... */ } // independently of one another.
var promises = [
foo(),
bar(),
baz()
];
// Option 1: Do stuff with array of results
Q.all(promises).then(function(arrayOfResults) {
console.log(arrayOfResults[0]); // resolve value from foo
console.log(arrayOfResults[1]); // resolve value from bar
console.log(arrayOfResults[2]); // resolve value from baz
});
// Option 2: Do stuff with results separated into individual variables via `spread()`
Q.all(promises).spread(function(fooResult, barResult, bazResult) {
// do stuff with the 3 arguments
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment