在类中实现链式es6承诺

时间:2015-07-24 16:34:09

标签: javascript promise ecmascript-6 es6-promise

我对es6承诺中this的背景感到有些困惑。以下是一些使用Promise处理异步函数的代码。

/**
* Generic recreation of apple photobooth on electron (javascript practice)
*/
class Photobooth {
  constructor(height=320, width=320) {
    this._height = 320;
    this._width = 320;
    this.video = video ? $(video) : $(document.createElement('video'));
  }
  getStream() {
    return new Promise(function (resolve, reject) {
      return navigator.webkitGetUserMedia({ video: true }, resolve, reject);
    });
  }
  streamTo(stream, element) {
    element.appendChild(self.video);
    var self = this;
    return new Promise(function (resolve, reject) {
      self.video.attr('src', window.URL.createObjectUrl(stream));
      self.video.on('loadedmetadata', function () {
        self.video.get(0);
        resolve();
      });
    });
  }
}

我想实现链接,看起来如下所示。

Photobooth
  .getStream()
  .streamTo(document.body);

Lodash与链接有类似的功能。

// gets sorted scores for class.
_([
  { name: 'Jeff', scores: [0.78, 0.85] },
  { name: 'Jessica', scores: [0.84, 0.68] },
  { name: 'Tim', scores: [0.92, 0.67] }
])
  .pluck('scores')
  .flatten()
  .map(x => x * 100)
  .sortBy()
  .value();

如何在javascript中实现基于类的promise-chaining?

1 个答案:

答案 0 :(得分:1)

  

我对es6 promises中的上下文感到有点困惑

承诺没有什么特别之处,this一如既往。使用ES6,它确实简化了使用箭头函数进行promise回调的过程。

  

我想实现链接

目前,您的函数确实会返回promises,尽管它与then有关。对于自定义链接,如下划线那样,您必须在具有所需方法的自定义对象中包装数据(在本例中为promises)。

在您的特定情况下,您可能根本不使用getStream方法,它似乎是您的PhotoBoth实例的唯一目的,因此您可以将其直接放入构造函数中。我会做的

class Photobooth {
  constructor(video=document.createElement('video'), height=320, width=320) {
    this._height = 320;
    this._width = 320;
    this.video = $(video);
    this.initStream()
  }
  initStream() {
    this.stream = new Promise((resolve, reject) =>
      navigator.webkitGetUserMedia({video: true}, resolve, reject);
    );
  }
  streamTo(element) {
    this.video.appendTo(element);
    return this.stream.then((stream) => new Promise((resolve, reject) => {
      this.video.prop('src', window.URL.createObjectUrl(stream));
      this.video.on('loadedmetadata', function(e) {
        resolve(this);
      });
    }), (err) => {
      $(element).text("Failed to get stream");
      throw err;
    });
  }
}