结合承诺和链接

时间:2014-11-10 05:28:49

标签: javascript promise chaining method-chaining bluebird

是否有良好的设计模式来利用承诺,同时仍然支持链接?例如,假设我们有类似的东西:

function Foobar() {
  this.foo = function() {
    console.log('foo');
    return this;
  };

  this.bar = function () {
    console.log('bar');
    return this;
  };
}

var foobar = new Foobar();
foobar.foo().bar();

相反,我们改变使用promises的方法,例如

function Foobar() {
  this.foo = function() {
    var self = this;
    return new Promise(function (resolve, reject) {
      console.log('foo');
      resolve(self);
    });
  };
  ...
}

有没有办法做一些好事:

var foobar = new Foobar();
foobar.foo().bar().then(function () {
  // do something
});

3 个答案:

答案 0 :(得分:4)

  

相反,我们改变使用promises的方法,例如

this.foo = function() {
  var self = this;
  return new Promise(function (resolve, reject) {
    …
    resolve(self);
  });
};

我建议不要这样做。这只是惹麻烦。如果您的实例(或:它的修改)是您的计算结果,那么在该计算期间您的对象的状态(我假设您使用OOP来封装状态)是什么?如果从事件循环的不同进程(线程)转换调用此(或任何其他)方法会发生什么?你必须走下整个兔子洞......

尽可能尝试使用函数式编程。

  

有没有办法做一些好事:

new Foobar().foo().bar().then(function () {
  // do something
});

是的,但每次调用后都必须使用.then

new Foobar().foo().then(function(foobar) {
  return foobar.bar();
}).then(function(barresult) {
  // do something
});

Bluebird库(和其他一些人一样)甚至还有.call()的实用功能。所以你要做

new Foobar().foo().call("bar").then(function(barresult) {
  // do something
});

答案 1 :(得分:1)

只需使用。

function Foobar() {
  this.foo = function() {
    var self = this;
    return new Promise(function (resolve, reject) {
      console.log('foo');
      resolve(self);
    });
  };
  this.bar = function() {
    var self = this;
    return new Promise(function (resolve, reject) {
      console.log('bar');
      resolve(self);
    });
  }
}

new Foobar().foo().then(function(foobar) { return foobar.bar(); });

答案 2 :(得分:0)

有一个方便的.call方法,允许您在已解析的值上调用方法。在一些情况下,我发现它非常方便:https://github.com/petkaantonov/bluebird/blob/master/API.md#callstring-propertyname--dynamic-arg---promise