Skip to content

Instantly share code, notes, and snippets.

@zjkuang
Last active July 25, 2023 16:09
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 zjkuang/5e86fec7a691584a13ee19e9db3cdc9a to your computer and use it in GitHub Desktop.
Save zjkuang/5e86fec7a691584a13ee19e9db3cdc9a to your computer and use it in GitHub Desktop.
// TypeScript Playground - https://www.typescriptlang.org/play
////////////////////////////////////////////////////////////////////////////////
// Start multiple promises simultaneously and execute them in parallel
const p1 = new Promise((resolve) => {
setTimeout(() => {
const result = Date();
console.log(`r1: ${result}`);
resolve(result);
}, 1000);
});
const p2 = new Promise((resolve) => {
setTimeout(() => {
const result = Date();
console.log(`r2: ${result}`);
resolve(result);
}, 2000);
});
const p3 = new Promise((resolve) => {
setTimeout(() => {
const result = Date();
console.log(`r3: ${result}`);
resolve(result);
}, 3000);
});
// Start all simultaneously
const p123 = Promise.all([p1, p2, p3])
.then(([r1, r2, r3]) => {
// The following 2 lines of console.log can verify that p1, p2, p3 were executed in parallel (not sequentially)
console.log(`[r1, r2, r3]: ${JSON.stringify([r1, r2, r3])}`);
console.log('p123 = Promise.all([p1, p2, p3]): ', Date());
// output of above:
// [LOG]: "[r1, r2, r3]: ["Fri Jul 30 2021 13:13:51 GMT-0600 (CST)","Fri Jul 30 2021 13:13:52 GMT-0600 (CST)","Fri Jul 30 2021 13:13:53 GMT-0600 (CST)"]"
// [LOG]: "Promise.all: ", "Fri Jul 30 2021 13:13:53 GMT-0600 (CST)"
return [r1, r2, r3];
});
// async-await way of parallel execution
async function f() {
const r123 = await Promise.all([p1, p2, p3]) // await p123;
console.log(`r123: ${JSON.stringify(r123)}`);
}
f();
////////////////////////////////////////////////////////////////////////////////
// Promise.all() example
const working: () => Promise<string> = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('working() completed with success');
}, 1000);
});
};
const notWorking: () => Promise<any> = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject('notWorking() failed');
}, 2000);
});
};
const bothPromises: Promise<any>[] = [
working().then((result) => {
return result;
}),
notWorking().then((result) => {
return result;
}).catch((reason) => { // If we omit this catch() branch, Promise.all(bothPromises) will never receive result
console.log('notWorking() failed');
}),
];
Promise.all(bothPromises).then((result) => {
console.log('Promise.all(): ', JSON.stringify(result));
});
// Similarly we can have Promise.race(), Promise.any()
////////////////////////////////////////////////////////////////////////////////
// An example of throwing a Promise.reject() from .then()
function pf(control: number): Promise<number> {
return new Promise<number>((resolve, reject) => {
setTimeout(() => {
if (control >= 0) {
resolve(control);
}
reject(`error code: ${control}`);
}, 1000);
});
}
function test(control: number) {
pf(control)
.then((result) => {
if (result === 0) {
return Promise.reject('zero');
}
console.log('success');
return result;
})
.catch((reason) => {
console.log(`failure: ${JSON.stringify(reason)}`);
return Promise.reject(reason);
});
}
test(-1); // rejected directly by pf
test(0); // resolved by pf by a reject is thrown by test from pf().then()
test(1); // resolved
////////////////////////////////////////////////////////////////////////////////
// An example of implementing Promise.any()
// We made this because for node version under v15, any() is not available for Promise
async function asyncCall1() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const message = 'F1: No!';
console.log(message);
reject(message);
}, 100);
});
}
async function asyncCall2() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const message = 'F2: Yes!';
console.log(message);
resolve(message);
}, 1000);
});
}
async function asyncCall3() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const message = 'F3: No!';
console.log(message);
reject(message);
}, 1500);
});
}
interface FailureRecord {
failed?: boolean | undefined;
reason?: any;
}
function anyOfPromises(asyncCalls: (() => Promise<any>)[]): Promise<any> {
return new Promise((resolve, reject) => {
let fulfilled = false;
let failures: FailureRecord[] = Array.from({length: asyncCalls.length}, () => ({}));
console.log(`failures: ${JSON.stringify(failures)}`);
asyncCalls.forEach((asyncCall, index) => {
asyncCall().then((value) => {
if (fulfilled) { return; }
fulfilled = true;
resolve(value);
}).catch((reason) => {
if (fulfilled) { return; }
failures[index] = {
failed: true,
reason,
};
const allFailed = failures.every((v) => Boolean(v.failed));
if (allFailed) {
reject({failures});
}
});
});
});
}
anyOfPromises([asyncCall1, asyncCall2, asyncCall3]).then((v) => {
console.log(`Fulfilled. ${JSON.stringify(v)}`);
}).catch((reason) => {
console.log(`All failed. ${JSON.stringify(reason)}`);
});
////////////////////////////////////////////////////////////////////////////////
// Some interesting usage of `await` call
const refreshToken = async (tag: string) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
const newToken = new Date().toISOString();
console.log(tag, '::', 'new generated:', newToken);
resolve(newToken);
}, 2000);
});
}
const test1 = async () => {
const p = refreshToken('test1');
const callP = async (tag: string) => {
try {
const result = await p;
console.log(tag, '::', JSON.stringify(result));
} catch (error) {
console.log(tag, '::', JSON.stringify(error));
} finally {
console.log(tag, '::', 'finally');
}
};
callP('1-1');
setTimeout(() => {
callP('1-2');
}, 1000);
};
const test2 = async () => {
const p = refreshToken('test2');
const callP = async (tag: string) => {
try {
const result = await p;
console.log(tag, '::', JSON.stringify(result));
} catch (error) {
console.log(tag, '::', JSON.stringify(error));
} finally {
console.log(tag, '::', 'finally');
}
};
callP('2-1');
setTimeout(() => {
callP('2-2');
}, 3000);
};
const test3 = async () => {
const _p = refreshToken('test3');
};
test1();
test2();
test3();
////////////////////////////////////////////////////////////////////////////////
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment