Last active
October 26, 2018 17:17
-
-
Save Serabe/6425dcb0af7e2bcae5c0dacc1dfaee3d to your computer and use it in GitHub Desktop.
Custom impl for Promise.all and Promise.race
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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