Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@peerreynders
Last active August 2, 2020 01:19
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 peerreynders/d94724f8ec0044475de1769a8fc3ae2b to your computer and use it in GitHub Desktop.
Save peerreynders/d94724f8ec0044475de1769a8fc3ae2b to your computer and use it in GitHub Desktop.
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'
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
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