Create a gist now

Instantly share code, notes, and snippets.

@brion /sample1.js
Last active Oct 1, 2016

ES2017 async/await vs ES2015 Promise vs ES5 plus Promise polyfill
// ES2017
class StreamFile {
/**
* Wait until the given number of bytes are available to read, or end of file.
* @param {number} nbytes - max bytes to wait for
* @param {Object?} cancelToken - optional cancellation token
*/
async buffer(nbytes, cancelToken) {
if (!this.loaded) {
throw new Error('cannot buffer when not loaded');
} else if (this.buffering) {
throw new Error('cannot buffer while buffering');
} else if (this.seeking) {
throw new Error('cannot buffer while seeking');
} else if (nbytes !== (nbytes | 0)) {
throw new Error('read with invalid byte count');
} else if (nbytes <= 0) {
throw new Error('read with negative or 0 bytes');
}
const end = this._clampToLength(this.offset + nbytes);
const readable = end - this.offset;
if (this.bytesAvailable(readable) >= readable) {
// Requested data is immediately available.
} else {
this.buffering = true;
try {
// If we don't already have a backend open, start downloading.
await this._triggerDownload(cancelToken);
const remainder = end - this._cache.writeOffset;
if (remainder > 0) {
await this._backend.buffer(remainder, cancelToken);
}
} finally {
this.buffering = false;
}
}
}
}
// ES2015
class StreamFile {
/**
* Wait until the given number of bytes are available to read, or end of file.
* @param {number} nbytes - max bytes to wait for
* @param {Object?} cancelToken - optional cancellation token
*/
buffer(nbytes, cancelToken) {
return new Promise((resolve, reject) => {
if (!this.loaded) {
throw new Error('cannot buffer when not loaded');
} else if (this.buffering) {
throw new Error('cannot buffer while buffering');
} else if (this.seeking) {
throw new Error('cannot buffer while seeking');
} else if (nbytes !== (nbytes | 0)) {
throw new Error('read with invalid byte count');
} else if (nbytes <= 0) {
throw new Error('read with negative or 0 bytes');
}
const end = this._clampToLength(this.offset + nbytes);
const readable = end - this.offset;
if (this.bytesAvailable(readable) >= readable) {
// Requested data is immediately available.
resolve();
} else {
this.buffering = true;
// If we don't already have a backend open, start downloading.
this._triggerDownload(cancelToken).then(() => {
const remainder = end - this._cache.writeOffset;
if (remainder > 0) {
return this._backend.buffer(remainder, cancelToken);
}
}).then(() => {
this.buffering = false;
resolve();
}).catch((err) => {
this.buffering = false;
reject(err);
});
}
});
}
}
// ES5 with polyfill for Promise
function StreamFile() {}
/**
* Wait until the given number of bytes are available to read, or end of file.
* @param {number} nbytes - max bytes to wait for
* @param {Object?} cancelToken - optional cancellation token
*/
StreamFile.prototype.buffer = function(nbytes, cancelToken) {
var self = this;
return new Promise(function(resolve, reject) {
if (!self.loaded) {
throw new Error('cannot buffer when not loaded');
} else if (self.buffering) {
throw new Error('cannot buffer while buffering');
} else if (self.seeking) {
throw new Error('cannot buffer while seeking');
} else if (nbytes !== (nbytes | 0)) {
throw new Error('read with invalid byte count');
} else if (nbytes <= 0) {
throw new Error('read with negative or 0 bytes');
}
var end = self._clampToLength(self.offset + nbytes);
var readable = end - self.offset;
if (self.bytesAvailable(readable) >= readable) {
// Requested data is immediately available.
} else {
self.buffering = true;
// If we don't already have a backend open, start downloading.
self._triggerDownload(cancelToken).then(function() {
var remainder = end - self._cache.writeOffset;
if (remainder > 0) {
return self._backend.buffer(remainder, cancelToken);
}
}).then(function() {
self.buffering = false;
resolve();
}).catch(function (err) {
self.buffering = false;
reject(err);
});
}
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment