连锁承诺并保留“这个”

2024-03-09

我有一个点击处理程序,需要一个接一个地进行多个异步调用。我选择使用承诺来构建这些调用(RSVP https://github.com/tildeio/rsvp.js,准确地说)。

下面,您可以看到clickA处理程序,在控制器内部(这是一个 Ember 应用程序,但我认为问题更普遍):

App.SomeController = Ember.Controller.extend({

  actions: {

    clickA: function() {
      var self = this;

      function startProcess() {
        return makeAjaxCall(url, {
          'foo': self.get('foo')
        });
      }

      function continueProcess(response) {
        return makeAjaxCall(url, {
          'bar': self.get('bar')
        });
      }

      function finishProcess(response) {
        return new Ember.RSVP.Promise(...);
      }

      ...

      startProcess()
        .then(continueProcess)
        .then(finishProcess)
        .catch(errorHandler);
    }
  }
});

它看起来很棒,但现在我必须添加第二个操作来重用某些步骤。

由于每个内部函数都需要访问控制器的属性,一种解决方案是将它们设为控制器的方法:

App.SomeController = Ember.Controller.extend({

  startProcess: function() {
    return makeAjaxCall(url, {
      'foo': this.get('foo')
    });
  },

  continueProcess: function(response) {
    return makeAjaxCall(url, {
      'bar': this.get('bar')
    });
  },

  finishProcess: function(response) {
    return new Ember.RSVP.Promise(...);
  },

  actions: {
    clickA: function() {
      this.startProcess()
        .then(jQuery.proxy(this, 'continueProcess'))
        .then(jQuery.proxy(this, 'finishProcess'))
        .catch(jQuery.proxy(this, 'errorHandler'));
    },

    clickB: function() {
      this.startProcess()
        .then(jQuery.proxy(this, 'doSomethingElse'))
        .catch(jQuery.proxy(this, 'errorHandler'));
    }
  }
});

所以,我的问题是:有更好的方法吗?我可以摆脱所有这些吗jQuery.proxy()以某种方式打电话?


解决方案是使用更好的承诺库。

Bluebird https://github.com/petkaantonov/bluebird has a bind https://github.com/petkaantonov/bluebird/blob/master/API.md#binddynamic-thisarg---promise函数,它允许您将上下文绑定到整个承诺链(您传递给的所有函数then or catch or finally在此上下文中调用)。

这是一篇关于绑定承诺的文章(我写的),就像您想要保留控制器/资源一样:使用绑定 Promise 来简化 Node.js 中的数据库查询 http://canop.org/blog/?p=516

我这样建立我的承诺:

// returns a promise bound to a connection, available to issue queries
//  The connection must be released using off
exports.on = function(val){
    var con = new Con(), resolver = Promise.defer();
    pool.connect(function(err, client, done){
        if (err) {
            resolver.reject(err);
        } else {
            // the instance of Con embeds the connection
            //  and the releasing function
            con.client = client;
            con.done = done;
            // val is passed as value in the resolution so that it's available
            //  in the next step of the promise chain
            resolver.resolve(val);
        }
    });
    // the promise is bound to the Con instance and returned
    return resolver.promise.bind(con);
}

这允许我这样做:

db.on(userId)          // get a connection from the pool
.then(db.getUser)      // use it to issue an asynchronous query
.then(function(user){  // then, with the result of the query
    ui.showUser(user); // do something
}).finally(db.off);    // and return the connection to the pool 
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

连锁承诺并保留“这个” 的相关文章

随机推荐

  • WebSocket 慢 - Java 和 JavaScript

    我正在处理我的世界插件的编码 但现在我遇到了以下问题 我的 websocket 服务器响应非常非常慢 这是我的 WebSocketClass 用于插件 套接字服务器类 package me mickerd pcoc import java
  • 约束包含仅适用于概念吗?

    考虑这个例子 template
  • 以与输入 R 相同的格式在 R 中输出向量

    也许我在想象这一点 但我认为有一个内置的 R 函数 可以让您以用于输入该对象的格式打印 R 向量 以及可能的其他对象 如矩阵和数据帧 返回为一个字符串 例如 gt x lt c 1 2 3 gt x 1 1 2 3 gt magical f
  • 从表中随机获取3条记录

    我已经阅读了类似查询的多个答案 但似乎没有一个能切中要害 假设我有一个包含 10 行的表 如何使用实体框架从该表中检索 3 个随机行 不只是 1 个随机行 而是 3 个随机行 每行都彼此不同 提前致谢 var threeRandomFoos
  • 如何在Android应用程序中自动填充编辑文本?

    我正在开发一款安卓应用程序 其中我有一些产品和购买该产品的表格 在订单表格中 我有一个 编辑文本作为产品 指产品名称 在我的应用程序中 用户必须输入产品名称 但我想知道有什么方法可以 EditText 字段会自动填充特定的产品 就像 Fli
  • c# 使用linq对数据表中的多列进行分组

    我的数据表中有三列 字符串 日期时间和小数 我想按字符串和小数列进行分组 对于分组的行 我想对小数值求和 我知道如何进行求和部分 但是如何对数据表中的两个不同列进行分组 这是我到目前为止无法正常工作的代码 var newSort from
  • Java - 在两个不同的数组中查找唯一元素

    我需要找到两个不同数组中的唯一元素 public static void main String args TODO Auto generated method stub int arr1 new int 1 2 3 4 5 6 int a
  • 如何清除mysql中的查询缓存?

    我在 root 提示符下尝试过此操作 但没有帮助 mysql gt RESET QUERY CACHE 这显示了 Query OK 0 rows affected 0 00 sec 但历史依然存在 如何清除或删除我输入的查询的历史记录 查询
  • 面向服务的架构建议

    出于个人和大学研究的原因 我正在考虑使用面向服务的架构构建一个简单的 CRM 其意义只是解释架构本身 并非商业用途 我正在考虑实施一个 CRM 提供简单的分析服务和客户服务 用户存储 个人评论和其他一些东西 我正在设计的架构定义 WebGU
  • 在尝试以下发现的实现后,没有可用于“事务可选”的持久性提供程序:

    我正在尝试使用 JPA 2 0 创建一个 Google App Engine GAE 我已遵循我需要的所有操作 将正确的 jar 放入类路径中并确保我的实体得到增强 但我在创建 EntityManager 时遇到问题 我的 persiste
  • 在 Python Pandas DataFrame 或 Jupyter Notebooks 中包装列名称

    我的数据框中的某些列的标题很长 并且我希望能够自动换行文本 我知道这个功能内置在 pandas 中 就像我一样 pd DataFrame np random randn 2 10 columns Very Long Column Title
  • 相当于 Mac 上的 MFMailComposer

    iOS 有不错的MFMailComposer让用户撰写电子邮件的类 在 Mac Mail 中打开新窗口并使用预先格式化的电子邮件的最佳方式是什么 就像通过 Mountain Lion 和 Reeder 应用程序中的 Safari 共享按钮完
  • 将 for-compression 与 scala.util.Try 一起使用时快速失败

    我很喜欢scala util Try在 Scala 2 10 中 以及它如何与 for compression 配合使用 使得处理可能容易出错的多个步骤 例如 我们可以使用以下代码来确保当且仅当一切都在控制之下并且我们正确获取值时才打印出这
  • 如何在 Magento 的非 EAV 模型中使用 setPage() 进行分页/限制?

    我需要得到 collection gt setPage 0 10 在我的非 EAV 模型上工作 但它不起作用 我已经尝试过了 matches gt getSelect gt setPage 0 10 但这没有帮助 The setPage 方
  • 将字符串拆分为具有特定模式和条件的部分

    我有类似下面的大约 5k 字符串的数组作为某些应用程序的输出 出于安全原因 我可能不会提供确切的数据 但示例格式与实际数据非常相似 kasdfhkasdhfaskdfj42345sdsadkfdkfhasdf5345534askfhsad
  • Pascal 中的“#”符号是什么?

    例如 x 123 我尝试在谷歌上搜索 但我根本不知道这意味着什么 IIRC 它表示数字的字符值 例如 32 gt 空格
  • 撤消系列差异

    我有一个包含每月数据的 pandas 系列 df sales 我需要减去 12 个月前的数据来拟合时间序列 所以我运行了以下命令 sales new df sales diff periods 12 然后我拟合了 ARMA 模型 并预测了未
  • SKEase动作,如何使用Float改变Action Setter Block?

    在下面的用例中 我尝试为lineWidth of an SKShapeNode SKEase 是精彩的一部分SpriteKit缓动 https github com craiggrummitt SpriteKitEasingSwift来自
  • 如何从 vbscript 中的 html 页面中提取值 - 我尝试了 MSXML2.DOMDocument

    下面是我尝试从网页中的节点获取值的一些代码 但在尝试设置 objNode 时失败 非常感谢任何帮助 Dim objHttp sWebPage objNode objDoc Set objDoc CreateObject MSXML2 DOM
  • 连锁承诺并保留“这个”

    我有一个点击处理程序 需要一个接一个地进行多个异步调用 我选择使用承诺来构建这些调用 RSVP https github com tildeio rsvp js 准确地说 下面 您可以看到clickA处理程序 在控制器内部 这是一个 Emb