javascript - 如何使用 Promise.all 避免 promise 构造函数反模式

标签 javascript node.js promise ecmascript-6 bluebird

在使用多个 promise 和 Promise.all 时如何避免 promise 构造函数反模式?

假设我有以下代码:

getFoo = function() {
    return new Promise(function(resolve, reject) {
        var promises = [];
        promises.push(new Promise(function(resolve, reject) => {
            getBar1().then(function(bar1) {
                processBar1(bar1); 
                resolve(bar1);
            });
        }));
        promises.push(new Promise(function(resolve, reject) => {
            getBar2().then(function(bar2) {
                processBar2(bar2); 
                resolve(bar2);
            });
        }));
        Promise.all(promises).spread(function(bar1, bar2) {
            var result = processBothBars(bar1, bar2);
            resolve(result);
        });
    });
}

它提出了反模式的一些基本问题,错误被吞没,以及厄运金字塔。

顺便说一句,我正在使用 Bluebird 。

最佳答案

您可以一起摆脱 new Promise

getFoo = function() {
    var promises = [];
    promises.push(getBar1().then(function(bar1) {
        processBar1(bar1);
        return bar1;
    }));
    promises.push(getBar2().then(function(bar2) {
        processBar2(bar2);
        return bar2;
    }));
    return Promise.all(promises).spread(function(bar1, bar2) {
        var result = processBothBars(bar1, bar2);
        return result;
    });
}

// start mock
function getBar1() {
    return Promise.resolve({name:'bar1',processed: false});
}
function getBar2() {
    return Promise.resolve({name:'bar2',processed: false});
}
function processBar1(bar1) {
  bar1.processed = true;
}
function processBar2(bar2) {
  bar2.processed = true;
}
function processBothBars (bar1, bar2) {
  return [bar1, bar2].filter(function (bar) {
    return bar.processed;
  }).map(function (bar) {
    return bar.name;
  });
}
Promise.prototype.spread = function (fn) {
  return this.then(function (arr) {
      return fn.apply(this, arr);
  });
};
// end mock

var 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;
    }));
    return Promise.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 返回一个 promise,因此除非您想防止错误到达外部 promise,否则无需创建一个新的包装它。

关于javascript - 如何使用 Promise.all 避免 promise 构造函数反模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32214322/

相关文章:

javascript - 如何使用 superagent 发送 FormData 对象

javascript - OO JavaScript 回调 : Am I doing it right?

javascript - 页面不加载路由器模式 : history on Apache

Javascript 相对 URL 的解析方式因主机而异

node.js - RethinkDB更新事务性能

mysql - 获取 SequelizeConnectionRefusedError : when running docker with sequelize

循环内的 Javascript Promise.all()

javascript - 如何从第一个 promise 列表构造第二个 promise 列表并迭代

javascript - 选择文本时不要触发 onfocus?

javascript - 在对象数组的数组中运行 Promise