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

2024-03-17

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

假设我有以下代码:

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);
        });
    });
}

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

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


你可以摆脱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返回一个承诺,因此不需要创建一个新的承诺来包装它,除非您想防止错误到达外部承诺。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 Promise.all 避免 Promise 构造函数反模式 的相关文章

  • 未捕获的类型错误:无法读取未定义的属性“toLowerCase”

    我收到此错误 它源自 jquery 框架 当我尝试加载准备好的文档上的选择列表时 出现此错误 我似乎无法找到为什么会出现此错误 它适用于更改事件 但在尝试手动执行该函数时出现错误 未捕获的类型错误 无法读取未定义的属性 toLowerCas
  • 将随机字符串转换为十六进制颜色

    我的应用程序中有一个操作日志表 我想根据该条目的 sessionID 为行分配随机颜色 以帮助查看模式 分组操作 到目前为止我有这个 console log stringToColorCode mj3bPTCbIAVoNr93me1I fu
  • 如何在 Javascript 中动态创建一个适用于所有浏览器的单选按钮?

    使用例如动态创建单选按钮 var radioInput document createElement input radioInput setAttribute type radio radioInput setAttribute name
  • Javascript:混合构造函数模式和揭示模块模式

    有什么方法可以让 Javascript 类扩展通过揭示模块模式创建的对象吗 我尝试了下面的代码 但是有没有办法实现同样的事情 sv MergeQuestionViewModel function this sv QuestionDetail
  • 如何创建一个多重过滤函数来过滤掉多个属性?

    我有一个要过滤的对象数组 name Apple age 24 model Android status Under development name Roboto age 24 model Apple status Running 我需要使
  • 在每页上插入折叠标记 (wkhtmltopdf)

    我正在使用 wkhtmltopdf 0 12 2 1 创建发票等 我需要在 pdf 的每一页上显示折叠标记 如果内容大于一页 如何在每个页面上使用 javascript 重复它们 这是我的基本标记 div class marks div c
  • 通过 Javascript 将图像切割成碎片

    我正在创建一个简单的拼图游戏 为了做到这一点 我需要将我正在使用的图片切成 20 块 Javascript 有没有办法将一张图片切成 20 个相等的部分 并将它们保存为网页中的 20 个不同的对象 或者我只需要进入 Photoshop 自己
  • 使用 jquery 通配符检查 cookie 名称

    我有一个生成动态 cookie 的表单 例如 webform 62 1234356 62 1234356 可以是任意数字 我需要使用一些通配符检查来检查名称以 webform 开头的 cookie 是否存在 下面不起作用 if cookie
  • Backbone 中的加载栏

    我想显示加载消息 图标 直到列表中的所有项目都已呈现 这是我的示例中的 jsfiddle http jsfiddle net 9R9zU 58 http jsfiddle net 9R9zU 58 我尝试在 Feed 部分添加一个带有加载栏
  • 嵌套辅助函数和性能

    嵌套辅助函数对于使代码更易于理解非常有用 谷歌甚至建议在他们的应用程序中使用嵌套函数时尚指南 https google styleguide googlecode com svn trunk javascriptguide xml Nest
  • 如何创建自定义元素扩展类的新实例

    我正在尝试以下示例谷歌开发者网站 https developers google com web fundamentals getting started primers customelements extendhtml我收到错误 Typ
  • Javascript 正则表达式来匹配正则表达式

    我正在研究一个特殊的正则表达式来匹配 javascript 正则表达式 现在我有这个正则表达式工作 i g m 例如 foo match i g m gt foo foo undefined foo i match i g m gt foo
  • 为什么 document.getelementbyId 在 Firefox 中不起作用?

    我不明白为什么 document getElementById 在 Firefox 中不起作用 document getElementById main style width 100 当我检查 Firebug 时 它说 类型错误 docu
  • 水平平滑滚动 100px

    Heyjo problem 一周以来我一直在寻找 javascript 或 jQuery 代码 以便在我的网站上实现滚动按钮 我失败的那一刻是按钮应该多次工作的时候 他的任务不是滚动到专用元素 而是应该向左滚动 例如 100px 此外 滚动
  • 通过多个回调优雅地传递“点击事件”

    当未登录的用户单击给定的按钮时 我想停止该事件 收集他的 oauth 收集他的电子邮件 如果我没有 然后执行该事件 我想用 javascript 来做所有事情 因为这会让事情变得更加简单 这就是我执行它的方式 我有两个问题 有没有更优雅的方
  • D3v6 嵌套图 - 嵌套 join()?

    我想可视化每个节点的 孩子 洞察力 我猜 D3v6 join 函数可以嵌套 不幸的是我找不到任何例子 下面的代码片段包含一个具有 3 个节点和子节点作为属性的outerGraph 到目前为止 这些孩子还没有被使用 相反 innerGraph
  • ExpressJS - DELETE 请求后 res.redirect

    我一直在寻找如何执行此操作 我正在尝试在发出删除请求后重定向 这是我正在使用的代码没有重定向 exports remove function req res var postId req params id Post remove id p
  • Three.js WebGL 从着色器绘制圆形自定义填充和边框颜色

    我将 Three js 与 WebGLRenderer 一起使用 我试图找出或查看如何使用 CircleGeometry 绘制圆圈的示例 并能够从顶点或片段着色器控制其填充和边框颜色 如果不使用图像作为纹理 这是否可能 抱歉 如果这真的很简
  • 在角度控制器中监听文档事件

    如何捕获角度控制器中的事件 我有文档级事件 所以我需要在角度控制器中捕获事件 这可能吗 Update 我有独立的 js 文件来处理来自相机的一些操作 document addEventListener myCameraEvent handl
  • 利用重力效果拖动元素

    我想完成类似于 photoshop com 和此网站的功能 http mrdoob com projects chromeexperiments google gravity http mrdoob com projects chromee

随机推荐