将对象绑定到 Promise.then() 参数的正确方法

The correct way to bind object to Promise.then() argument

我发现不能简单地将对象的函数传递给 Bluebird then 的困难方法。我假设 Bluebird 的 then 正在做一些魔术并将传入的函数包装在匿名函数中。所以我在函数上附加了一个 .bind 并且它起作用了。这是用蓝鸟做这件事的正确方法吗?或者有更好的方法吗?

var Promise = require("bluebird")

var Chair = function(){
  this.color = "red"
  return this
}


Chair.prototype.build = function(wood){
  return this.color + " " + wood
}

var chair = new Chair()

//var x = chair.build("cherry")

Promise.resolve("cherry")
  .then(chair.build.bind(chair)) // color is undefined without bind
  .then(console.log)

我知道 none 这是异步的,所以请使用同步示例,我的用法是异步的。

So I attached a .bind to the function and it worked. Is this the correct way to do this with bluebird?

是的,这是保留上下文的一种方法。您还可以传递一个匿名函数(您可能已经知道这一点)。

Promise.resolve("cherry")
    .then(function (value) {
        return chair.build(value);
    })
    .then(console.log);

Or is there some better way?

你其实可以用bluebird的Promise.bind方法,像这样

Promise.resolve("cherry")
  .bind(chair)
  .then(chair.build)
  .then(console.log)

现在,无论何时在函数内部调用 Promise 处理程序(完成处理程序或拒绝处理程序),this 将仅引用 chair 对象。


注1:在这个特定的例子中,console.log也得到this作为chair对象,但是它仍然可以正常工作,因为在 Node.js 中,console.log 函数不仅在原型上定义,还在对象本身上定义,绑定到 console 对象。对应的代码为here.

注2:如果不同的处理程序需要不同的上下文,那么最好写匿名函数。在那种情况下,Promise.bind 将无济于事。但是如果你选择使用它,那么你必须为每个处理程序使用不同的上下文,你的代码可能看起来像这样

var chair1 = new Chair("red")
var chair2 = new Chair("green")

Promise.resolve("cherry")
    .bind(chair1)            // Changing the binding to `chair1`
    .then(chair1.build)
    .tap(console.log)
    .bind(chair2)            // Changing the binding to `chair2`
    .then(chair2.build)
    .tap(console.log);