How Do You Avoid The Promise Constructor Antipattern With Promise.all
How do you avoid the promise constructor antipattern when using multiple promises and Promise.all? Say I have the following code: getFoo = function() { return new Promise(funct
Solution 1:
You can just get rid of new Promise
all together.
getFoo = function() {
var promises = [];
promises.push(getBar1().then(function(bar1) {
processBar1(bar1);
return bar1;
}));
promises.push(getBar2().then(function(bar2) {
processBar2(bar2);
return bar2;
}));
returnPromise.all(promises).spread(function(bar1, bar2) {
var result = processBothBars(bar1, bar2);
return result;
});
}
// start mockfunctiongetBar1() {
returnPromise.resolve({name:'bar1',processed: false});
}
functiongetBar2() {
returnPromise.resolve({name:'bar2',processed: false});
}
functionprocessBar1(bar1) {
bar1.processed = true;
}
functionprocessBar2(bar2) {
bar2.processed = true;
}
functionprocessBothBars (bar1, bar2) {
return [bar1, bar2].filter(function (bar) {
return bar.processed;
}).map(function (bar) {
return bar.name;
});
}
Promise.prototype.spread = function (fn) {
returnthis.then(function (arr) {
return fn.apply(this, arr);
});
};
// end mockvar getFoo = function (fail) {
var promises = [];
promises.push(getBar1().then(function (bar1) {
processBar1(bar1);
if (fail) {
throw'getBar1 Failed!';
}
return bar1;
}));
promises.push(getBar2().then(function (bar2) {
processBar2(bar2);
return bar2;
}));
returnPromise.all(promises).spread(function (bar1, bar2) {
var result = processBothBars(bar1, bar2);
return result;
});
}
getFoo().then(function (result) {
console.log(result); // ['bar1', 'bar2']
});
getFoo(true).then(function (result) {
console.log(result); // doesn't happen
}).catch(function (e) {
console.error(e); // Error: getBar1 Failed!
});
.then
returns a promise, so there's no need to create a new one that wraps it unless you want to prevent errors from reaching the outer promise.
Solution 2:
No need to create any promises of your own here because getBar1()
and getBar2()
both already return promises - at least we assume so because both are thenable.
Providing processBar1
and processBar2
each returns the result you are interested in, the code will simplify as follows :
var getFoo = function() {
// write promises as an array literalvar promises = [
getBar1().then(processBar1),//result returned by getBar1() is automatically passed to processBar1getBar2().then(processBar2) // ... ditto ...
];
returnPromise.all(promises).spread(processBothBars);
};
Solution 3:
Fwiw bluebird proves some sugar over this:
getFoo = function() {
returnPromise.join(getBar1().tap(processBar1),
getBar2().tap(processBar2),
processBothBars);
}
Post a Comment for "How Do You Avoid The Promise Constructor Antipattern With Promise.all"