Skip to content

Instantly share code, notes, and snippets.

@sasha240100
Created May 6, 2018 21:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sasha240100/149aa171acd95d81224e39647d32341d to your computer and use it in GitHub Desktop.
Save sasha240100/149aa171acd95d81224e39647d32341d to your computer and use it in GitHub Desktop.
const SYMBOL_RESOLVER = Symbol('RESOLVER');
const SYMBOL_REJECTOR = Symbol('REJECTOR');
const SYMBOL_STATUS = Symbol('STATUS');
const SYMBOL_VALUE = Symbol('VALUE');
const SYMBOL_SHADOW_RESOLVER = Symbol('SHADOW_RESOLVER');
class Promise2 {
static all(promises) {
const promisesData = [];
let resolvedCount = 0;
return new Promise2(resolve => {
promises.forEach((promise, index) => {
promise.then(value => {
promisesData[index] = value;
resolvedCount++;
if (resolvedCount === promises.length)
resolve(promisesData);
})
})
})
}
constructor(executor) {
this[SYMBOL_STATUS] = 'pending';
this[SYMBOL_RESOLVER] = null;
this[SYMBOL_REJECTOR] = null;
this[SYMBOL_VALUE] = null;
this[SYMBOL_SHADOW_RESOLVER] = null;
executor(data => { // resolve
if (this[SYMBOL_STATUS] !== 'pending') return;
this[SYMBOL_VALUE] = data;
this[SYMBOL_STATUS] = 'resolved';
if (this[SYMBOL_RESOLVER]) {
const returnedValue = this[SYMBOL_RESOLVER](this[SYMBOL_VALUE]);
if (this[SYMBOL_SHADOW_RESOLVER] && returnedValue && returnedValue instanceof this.constructor)
returnedValue.then(data => this[SYMBOL_SHADOW_RESOLVER](data));
}
}, data => { // reject
if (this[SYMBOL_STATUS] !== 'pending') return;
this[SYMBOL_VALUE] = data;
this[SYMBOL_STATUS] = 'rejected';
if (this[SYMBOL_REJECTOR]) {
const returnedValue = this[SYMBOL_REJECTOR](this[SYMBOL_VALUE]);
if (this[SYMBOL_SHADOW_RESOLVER] && returnedValue && returnedValue instanceof this.constructor)
returnedValue.then(data => this[SYMBOL_SHADOW_RESOLVER](data));
}
});
}
then(callback) {
if (this[SYMBOL_STATUS] === 'resolved')
return callback(this[SYMBOL_VALUE]);
else {
this[SYMBOL_RESOLVER] = callback;
return new this.constructor(resolve => {
this[SYMBOL_SHADOW_RESOLVER] = resolve;
});
}
}
catch(callback) {
if (this[SYMBOL_STATUS] === 'rejected')
return callback(this[SYMBOL_VALUE]);
else {
this[SYMBOL_REJECTOR] = callback;
return new this.constructor(resolve => {
this[SYMBOL_SHADOW_RESOLVER] = resolve;
});
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment