Last active
August 2, 2020 01:19
-
-
Save peerreynders/d94724f8ec0044475de1769a8fc3ae2b to your computer and use it in GitHub Desktop.
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
function log(value) { | |
console.log(value); | |
} | |
function executor(resolve, _reject) { | |
const resolveValue = () => resolve('3 Resolved now'); | |
self.setTimeout(resolveValue, 1000); | |
} | |
const pending = new Promise(executor); | |
pending.then(log); // '3 Resolved now' | |
// (after '1 Still pending' and '2 Resolved') | |
const resolved = Promise.resolve('2 Resolved'); | |
// If multiple values in the array are resolved | |
// then array ORDER breaks the tie. | |
// `pending` promise (first entry) is still pending. | |
// '1 Pending' (second entry) wins. | |
Promise.race([pending, '1 Still pending']).then(log); // '1 Still pending' | |
// `resolved` promise (first entry) is resolved. | |
// '2 Resolved' wins. | |
// '2 Still pending' (second entry) never gets a chance. | |
Promise.race([resolved, '2 Still pending']).then(log); // '2 Resolved' |
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
function makeResolvedOr(promise, defaultValue) { | |
let result = defaultValue; | |
// won't resolve within this microtask | |
promise.then(value => { | |
result = value; | |
}); | |
return () => result; | |
} | |
const p = Promise.resolve('2. Done'); | |
const availableResult = makeResolvedOr(p, '1. In Progress'); | |
queueMicrotask(() => { | |
console.log(availableResult()); // '2. Done' | |
}); | |
console.log(availableResult()); // '1. In Progress' | |
// https://twitter.com/PeerReynders/status/1289609763450425348 |
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
function notSettled(state) { | |
return 0 < state && state < 3; | |
} | |
function makeResultHolder(promise, initialValue) { | |
let holder = { | |
result: initialValue, | |
state: 1 // initializing | |
} | |
const resolveValue = value => { | |
if (notSettled(holder.state)) { | |
holder.state = 3; // resolved | |
holder.result = value; | |
} | |
}; | |
const errorState = error => { | |
holder.state = 0; // rejected | |
holder.error = error; | |
}; | |
// `unique` value "winning" the race | |
// means `promise` is still pending | |
// | |
const unique = Symbol('unique'); | |
const checkPending = value => { | |
if (holder.state === 1) { | |
if (value === unique) { | |
holder.state = 2; // pending | |
} else { | |
resolveValue(value) | |
} | |
} | |
return promise; | |
}; | |
Promise.race([promise, unique]) | |
.then(checkPending) | |
.then(resolveValue) | |
.catch(errorState); | |
return holder; | |
} | |
// | |
// Demonstration | |
// | |
let resolvePromise; | |
let rejectPromise; | |
const executor = (resolve, reject) => { | |
resolvePromise = () => resolve('Done'); | |
rejectPromise = () => reject(new Error('Failed')); | |
}; | |
// const p = Promise.resolve('Done fast'); | |
// const p = Promise.reject(new Error('Fail fast')); | |
const p = new Promise(executor); | |
let h = makeResultHolder(p, 'In progress'); | |
let holding = true; | |
const step = () => { | |
const state = h.state; | |
const message = state !== 0 ? | |
`(state, result): (${state}, ${h.result})` : | |
`(state, error): (${state}, ${h.error.message})`; | |
console.log(message); | |
if (notSettled(state)) { | |
if (holding && state === 2) { | |
holding = false; | |
resolvePromise(); | |
// rejectPromise(); | |
} | |
queueMicrotask(step); | |
} | |
}; | |
step(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment