使用 Promise 时保留变量的最佳实践[重复]

2024-04-12

我是 Promises 的新手,我想知道在沿着链向下的同时保留变量的最佳实践是什么?

通过 Promise 连接到 MongoDB 非常简单:

connectToMongoDB(data).done(function(db) {

    var collection = db.collection('test_inserts');
    // do more stuff here

});

但是如果我必须连接到两个不同的数据库会发生什么?

connectToMongoDB1(data1).then(function(db1) {

    return connectToMongoDB2(data2);

}).done(function(db2) {

    var collection = db1.collection('test_inserts');
    // ERROR: db1 is undefined

});

这个错误是完全有道理的。但我该如何转发db1不改变我的connectToMongoDB2()功能,因为我想保留connectToMongoDB2()我所有的承诺总的来说都很笼统?

我的意思是,我可以包裹一个对象来存储所有相关的东西,但这看起来有点老套:

var relevantStuff = {};

connectToMongoDB1(data1).then(function(db1) {

    relevantStuff.db1 = db1;
    return connectToMongoDB2(data2);

}).done(function(db2) {

    var collection = relevantStuff.db1.collection('test_inserts');
    // do more stuff here

});

最佳实践是什么?


注意:我正在使用bluebird https://github.com/petkaantonov/bluebird/在这个答案中。

有 3 种方法可以实现您想要的功能:闭包、绑定和Promise.using.

Closure这就是@Sukima 展示的方式。

function promisedFunc() {
    var db;
    return getCollection().then(function(col) {
        db = col;
        return db.query(stuff);
    }).then(function() {
        return db.query(otherStuff);
    });
}

Binding: using Promise.bind, 你(们)能做到this将保存值的对象。

function promisedFunc() {
    return getCollection().bind({}).then(function(col) {
        this.db = col;
        return this.db.query(stuff);
    }).then(function() {
        return this.db.query(otherStuff);
    });
}

Finally最后一种方法是由 bluebird v2 引入的,是使用真正的资源管理。

function promisedFunc() {
    return Promise.using(getDb(), function(db) {
        return db.query(stuff).then(function() {
            return db.query(otherStuff);
        });
    });
}

我将解释一下getDb方法再往下。


最后一种方法提供了另一个非常有趣的好处:处置资源。例如,您经常需要调用close数据库资源的方法。Promise.using允许您创建处置器,一旦其中的承诺得到解决(或未解决)就运行。

要了解为什么这是一个优势,让我们回顾一下实现此目的的 3 种方法。

Closure:

var db, close;
return getCollection().spread(function(col, done) {
    db = col;
    close = done;
    return db.query(stuff);
}).then(function() {
    return db.query(otherStuff);
}).finally(function() {
    close();
});

是的,这意味着每次使用数据库连接时都必须编写所有这些样板文件。没有其他选择。

现在我们看看绑定方式:

return getCollection().bind({}).spread(function(col, done) {
    this.db = col;
    this.close = done;
    return this.db.query(stuff);
}).then(function() {
    return this.db.query(otherStuff);
}).finally(function() {
    this.close();
});

然而现在,这可以模块化。

var db = {
    getDb: function() { return getCollection().bind({}); },
    close: function() { this.close(); }
};

return db.getDb().then(function() {
    return this.db.query(stuff);
}).then(function() {
    return this.db.query(otherStuff);
}).finally(db.close);

这已经好很多了!但我们还是要考虑使用finally.

然后按照bluebird介绍的方式,Promise.using。通过这样声明:

function getDb() {
    var close;
    return getCollection().spread(function(db, done) {
        close = done;
        return db;
    }).disposer(function() {
        close();
    });
}

您可以像以前一样简单地使用它:

return Promise.using(getDb(), function(db) {
    return db.query(stuff).then(function() {
        return db.query(otherStuff);
    });
});

无需思考finally,并且没有样板。

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

使用 Promise 时保留变量的最佳实践[重复] 的相关文章

  • 有没有办法将 Google 文档分割成多个 PDF?

    我想在 Google Scripts VBA 代码中复制我为 Word 文档编写的代码 基本上 它通过搜索我插入文档中的标签 将文档 切片 为多个 PDF 文件 目的是允许合唱团使用 forScore 管理乐谱的应用程序 在切片点插入先前注
  • npm WARN 已弃用 [email protected]:改用 uuid 模块

    当我尝试时 npm install g cordova latest总是得到npm 警告已弃用 电子邮件受保护 cdn cgi l email protection 使用 uuid 模块代替 mac 操作系统塞拉利昂 10 12npm v
  • Javascript - 使数组索引 toLowerCase() 不起作用

    我试图将所有数组索引设置为小写字符串 但它不起作用 我在这里查看了其他答案并尝试了他们的解决方案 例如使用toString 添加之前toLowerCase但它不起作用 这很奇怪 我创建了一个问题的jsfiddlehere https jsf
  • 通过 Javascript 更改 Webkit 属性?

    请帮助我 可能是因为我对 CSS 动画和 Javascript 相当陌生 但我使用的代码应该更改它的属性 当我运行代码时 它会执行代码中的所有其他操作 除了更改所需 div 的 CSS 属性 我已经尝试了所有这四种方法 但似乎都不起作用 它
  • 如何将节点 sqlite3 与 q (promise) 一起使用

    我正在尝试将 Promise 与 sqlite3 一起使用 这是我的源代码的一部分 this deleteTag function tag project var db this db if project return q nfcall
  • Express JS:请求的资源上不存在“Access-Control-Allow-Origin”标头

    我有一个在服务器上运行的 API 和一个连接到它以检索数据的前端客户端 我对跨域问题做了一些研究并使其发挥作用 但我不确定发生了什么变化 我现在在控制台中收到此错误 XMLHttpRequest 无法加载https api mydomain
  • 在each() 和forEach() 中使用break 和 continue

    如果我们不能使用 break 和 continue 关键字 我不确定我是否理解函数式循环 映射的价值 我可以做这个 collections users models forEach function item index can t use
  • Lightbox:如何翻译“Image x of x”文本?

    我使用 Lightbox 2 作为图像集 当我的网站的访问者单击该集中的缩略图时 它将显示 图像的放大版本 下面是 描述 取自 a 标题属性 其下方 文本 Image x of x 例如 Image 1 of 12 有谁知道在哪里翻译 更改
  • Flask 和 Reactjs 抛出 JSX 转换错误

    我已经开始将 ReactJS 与 Python Flask 后端结合使用 通过 Flask 渲染模板时 我在 Chrome 控制台中收到以下客户端错误 错误 找不到模块 jstransform visitors es6 templates
  • 在 Windows 上静默安装 Qt55 Enterprise

    编辑 在 Qt 支持的帮助下 我已经解决了如何自动化 Qt 企业安装程序的这两个部分 下面是脚本调用 我正在尝试在 Windows 8 1 和 Windows 10 上静默安装 Qt 5 5 1 Enterprise 使用 script 开
  • FullCalendar:如何重新创建/重新初始化 FullCalendar 或批量添加多个事件

    我正在尝试将新事件批量添加到日历中 但未能找到方便的使用方法 所以我决定用新的事件数组重新初始化视图 所以我尝试了以下方法 var events title Event start new Date y m d 10 description
  • 如何在使用类型分散时将箭头添加到行尾

    如何在 y 不等于 0 且系列类型以线宽 2 分散的情况下正确地将箭头添加到行的每一端 在这里我可以看到箭头已添加但未正确添加 请看这个 部分工作小提琴 http jsfiddle net vnYCX 这是我的 JS 最初的原型是由 sta
  • 如何使用 Node.js 解析 JSON? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我应该如何使用 Node js 解析 JSON 是否有一些模块可以安全地验证和解析 JSON 你可以简单地使用JSON parse h
  • 使用mockery和sinon模拟类方法

    我正在学习使用带有 sinon 的节点模块模拟进行单元测试 仅使用模拟和普通类 我就可以成功注入模拟 不过 我想注入一个 sinon 存根而不是一个普通的类 但我在这方面遇到了很多麻烦 我试图嘲笑的班级 function LdapAuth
  • 如何获取从 Express (Node.js) 中的表单传递的数据

    我想获取使用表单从页面传递的数据 并在重定向的页面中使用该数据 我的客户端有这个表格
  • 如何使 4.X Typescript 项目与旧版本的 Typescript(如 3.X)兼容?

    如何使基于 TS 4 X 构建的软件包与 3 X 兼容 例如 如果我有较新的版本 则使用新功能 否则使用any or unknown或旧版本支持的任何内容 有没有可能使用指令 https www typescriptlang org doc
  • 如何使用 API 中的数据填充选择的下拉元素 - ReactJS

    我对 React 还很陌生 我正在从 API 获取数据 当我检查控制台日志时可以看到数据 但是我不知道如何使用 map 创建一个新数组 然后选项元素可以使用该数组来显示货币代码 目前它填充下拉列表 但选项元素全部为空 结果显示为 NaN 下
  • Dojo“正在加载”消息

    我是 Dojo 新手 所以我需要一些帮助 我的一些链接需要一段时间 当用户单击时 页面开始加载需要几秒钟 我想添加一条 正在加载 消息 我可以用 旧时尚方式 来做 但我想学习新的 更简单 更智能的 Dojo 方式 具体如何工作现在并不重要
  • React Router Tabs——保持组件安装

    我使用 React Router 创建了选项卡 每个选项卡都有不同的路线 但是 我想通过保持隐藏选项卡的安装来维护选项卡转换之间的选项卡状态 我该如何实现这一目标 每次路由切换时 React 路由器都会重新安装每个组件 已经有人问过这个问题
  • javascript 闭包和对象引用

    我的情况有点晦涩难懂 主要是因为我认为我已经掌握了闭包 所以基本上我想要的是将集合重置为默认值 假设我有一个集合 它具有带有对象参数数组的构造函数 var c new collection x y z 然后集合定期更新 因为我没有保留数组的

随机推荐

  • 比较日期 < 或 DateDiff 哪个更好?

    哪个被认为更好 select from TableA where productDate lt 12 9 2013 or select from TableA where DATEDIFF day productDate 12 9 2013
  • 使用 drupal_get_form() 传递参数

    这是我使用钩子的自定义模块 假设如果我想将参数传递给 custom1 default form 函数调用 我应该如何传递参数
  • 方案:为什么内部定义比外部定义快?

    我尝试运行下面的程序 define odd internal x define even x if zero x t odd internal sub1 x if zero x f even sub1 x define odd extern
  • printf 类型提升和符号扩展

    我对 printf 和一般情况下类型提升如何发生感到困惑 我尝试了以下代码 unsigned char uc 255 signed char sc 128 printf unsigned char value d n uc printf s
  • 从 {AER} 的 ivreg() 获取第一阶段结果

    有没有办法从中提取第一阶段的结果ivreg 我想看看在不运行单独回归的情况下计算结果如何 这里有一些代码 其中包括 IV 以及我如何手动估计第一阶段以及通过进入第二阶段进行双重检查 library AER y lt rnorm 100 5
  • 反向传播实现问题

    我应该做什么 我有一个黑白图像 100x100px 我应该训练一个反向传播 http en wikipedia org wiki Backpropagation神经网络与该图像 输入是图像的 x y 坐标 从 0 到 99 输出是 1 白色
  • 使用tensorflow-gpu获得可重现的结果

    使用 Tensorflow 处理项目 但是 我似乎无法重现我的结果 我尝试过设置图形级别种子 numpy 随机种子甚至操作级别种子 然而 它仍然无法重现 在 Google 搜索中 大多数人都将罪魁祸首归咎于 reduce sum 函数 因为
  • AS3:将变量转换为动态类型

    是否可以动态地将变量转换为类型 其中类型将是类型的变量Class 考虑以下因素 无效 var myClass Class MyClass var myInstance myClass new myClass 对于上下文 我正在 Flex 4
  • 使用 Swift 以编程方式闪烁屏幕(在“屏幕截图”上)

    为了从这里转换 Objective C 示例 如何以编程方式闪烁屏幕 https stackoverflow com questions 5254508 how to flash screen programmatically我写了以下代码
  • 撤消核心数据更改的操作名称

    我正在寻找一种内置 或易于实现 的方法来让核心数据撤消 重做操作名称读起来像 撤消编辑名字 而不是像它们那样简单地 撤消 或 重做 默认情况下 我有一个核心数据应用程序 并且正在使用它NSUndoManager作为我的 Windows 撤消
  • Spring RedisTemplate:8次调用后方法键挂起

    我使用 Spring RedisTemplate spring data redis 1 7 1 与 Redis 进行通信 我需要通过正则表达式获取然后删除键 例如 context user1 我用的方法 RedisTemplate key
  • Dagger - 在不同组件上获取相同实例

    我遇到了类似的问题this https stackoverflow com questions 40745279 dagger 2 provide same instance between multiple component with
  • 如何用UML表示通信协议?

    在我的 UML 模型中 我有一个系统及其相互通信的子组件 例如 我有一台计算机和一个遥控机器人 它们通过蓝牙进行通信 目前图中的流程类似于 计算机 触发 遥控车 的 setVelocity 函数 在这一点上 我想通过说以下的话来完善沟通 计
  • 使用 Powershell 在单独的单独行上列出完全路径文件名?

    如果我执行 Get ChildItem ext recurse 输出由一系列目录部分组成 后跟由所述目录部分分隔的每个匹配文件的一列或多列信息 有类似 Unix find 命令的东西吗 其中每个匹配的文件名及其完整的相对路径都出现在一行中
  • 原生 JavaScript 中的 jQuery.getScript 替代方案

    我正在尝试动态加载 JS 脚本 但不能使用 jQuery 我检查了 jQuery 源代码以了解如何获取脚本 http api jquery com jQuery getScript 已实现 以便我可以使用该方法使用本机 JS 加载脚本 但是
  • Silverlight 绑定到 TranslateX

    我有一个简单的 winphone7 应用程序 但我认为这适用于任何 silverlight 基本上我有一个椭圆 我想用平移 X 和 Y 属性来移动它 这是我的尝试
  • 在.net winform中创建圆角容器

    我想在 winform net 中创建圆角容器 我的目标是创建一个容器 这样如果我将任何其他控件放入其中 该控件也将变成圆形 这可能吗 您正在寻找Control Region财产 http msdn microsoft com en us
  • PDF 可以在 Chrome 中呈现,但不能在 Acrobat 中呈现

    PDF 1 7 4 0 obj lt ObjStm N 3 First 14 Length 139 gt gt stream 1 0 2 41 3 76 lt Catalog Version 1 7 Pages 2 0 R gt gt lt
  • Vs2017:查找资源字典时出错

    当我尝试引用我的 app xaml 文件的资源字典时 出现以下错误
  • 使用 Promise 时保留变量的最佳实践[重复]

    这个问题在这里已经有答案了 我是 Promises 的新手 我想知道在沿着链向下的同时保留变量的最佳实践是什么 通过 Promise 连接到 MongoDB 非常简单 connectToMongoDB data done function