Reputation: 11187
I'm a bit confused by the context of this
in es6 promises. Here is some code that handles async functions with 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();
});
});
}
}
I want to implement chaining to look something like as follows.
Photobooth
.getStream()
.streamTo(document.body);
Lodash has a similar feature with chaining.
// 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();
How can this be class-based promise-chaining be implemented in javascript?
Upvotes: 0
Views: 441
Reputation: 664297
I'm a bit confused by the context of this in es6 promises
There's nothing special about promises, this
works as always. With ES6, it does simplify things to use arrow functions for the promise callbacks.
I want to implement chaining
Currently your functions do return promises, which do chain albeit with then
. For custom chaining, like underscore does it, you will have to wrap your data (in this case, the promises) in your custom objects that have the methods that you want.
In your specific case, you might however not use that getStream
method at all, it seems to be the only purpose of your PhotoBoth
instances so you can put it right into the constructor. I would do
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;
});
}
}
Upvotes: 1