Skip to content

Instantly share code, notes, and snippets.

@Serabe
Last active October 26, 2018 17:17
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 Serabe/6425dcb0af7e2bcae5c0dacc1dfaee3d to your computer and use it in GitHub Desktop.
Save Serabe/6425dcb0af7e2bcae5c0dacc1dfaee3d to your computer and use it in GitHub Desktop.
Custom impl for Promise.all and Promise.race
const callOnlyOnce = (fn) => {
let called = false;
return function() {
if (called) {
return;
}
called = true;
return fn.apply(this, arguments);
}
}
const timeoutPromise = (ms, value) => {
return new Promise(function(resolve) {
setTimeout(() => resolve(value), ms);
});
}
const timeoutRejectPromise = (ms, value) => {
return new Promise(function(resolve, reject) {
setTimeout(() => reject(value), ms);
});
}
const promiseRace = (promises) => {
return new Promise(function(rslv, rjct) {
let resolve = callOnlyOnce(rslv);
let reject = callOnlyOnce(rjct);
promises.forEach(p => p.then(resolve, reject));
});
}
const promiseAll = (promises) => {
return new Promise(function(rslv, rjct) {
let response = Array(promises.length);
let count = 0;
function check() {
count++;
if (count === promises.length) {
rslv(response);
}
}
function resolve(index) {
return (value) => {
response[index] = { status: 'resolved', value };
check();
}
}
function reject(index) {
return (error) => {
response[index] = { status: 'rejected', error };
check();
}
}
promises.forEach((promise, index) => {
promise.then(resolve(index), reject(index));
});
});
}
const promiseHash = (obj) => {
let keys = Object.keys(obj);
return new Promise(function(rslv) {
let response = Object.create(null);
let count = 0;
function check() {
count++;
if (count === promises.length) {
rslv(response);
}
}
function resolve(index) {
return (value) => {
response[keys[index]] = value;
check();
}
}
function reject(index) {
return (error) => {
response[keys[index]] = { status: 'rejected', error };
check();
}
}
keys.forEach((key, index) => {
Promise.resolve(obj[key]).then(resolve(index), reject(index));
});
});
}
promiseAll([
timeoutPromise(500, '1'),
timeoutRejectPromise(100, '2'),
timeoutPromise(5900, '3')
]).then((value) => console.log('Resolved: ', value), (error) => console.log('Reason: ', error));
let a, b;
op1
.then((value) => {
a = doSomethingElse();
return RSVP.hash({ a, value: fetch(a.url) });
}).then(({a, value}) => {
b = doSomething();
return RSVP.hash({ a, b, value: fetch(b.url) });
}).then(({a, b, value}) => {
// I need to do something with a and b.
});
async function main() {
try {
let value = await op1;
let a = doSomethingElse();
let aResponse = await fetch(a.url);
let b = doSomething();
let bResponse = await fetch(b.url);
console.log(a.url, b.url);
await Promise.all([aResponse, bResponse]);
} catch(e) {
console.log(e);
}
// Yes
let models = await Promise.all(urls.map(url => fetch(url)));
// No
for(let i = 0; i<urls.length; i++) {
await fetch(urls[i]);
}
}
await main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment