Skip to content

Instantly share code, notes, and snippets.

@danielscottjames
Last active March 16, 2023 16:31
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 danielscottjames/ac19596cbca67dec4280d655c74059c7 to your computer and use it in GitHub Desktop.
Save danielscottjames/ac19596cbca67dec4280d655c74059c7 to your computer and use it in GitHub Desktop.
TypeScript Async Code Examples
//@ts-check
/* #region Schedule a new task */
setTimeout(() => {
console.log("In Timeout");
}, 100);
console.log("After setTimeout");
/* #endregion */
/* #region No Preemption */
setTimeout(() => {
console.log("In Timeout");
}, 100);
const now = Date.now();
while (Date.now() - now < 5000); // Loop for 10 seconds
console.log("After setTimeout");
// Try this, run an infinite loop in a browser tab
/* #endregion */
/* #region Other source of async tasks */
const fs = require('fs');
// Other common sources: file system, network requests, Mouse/Keyboard events, requestAnimationFrame, etc...
fs.readFile('hello.txt', (err, result) => {
if (err) {
console.log(err);
} else {
console.log(result.toString());
}
});
setTimeout(() => console.log("In timeout"), 20);
console.log("After readFile");
// Question?: What order to the log statements execute in?
/* #endregion */
/* #region What is a Promise? */
// Encapsulates the state for a callback
const promise = new Promise((resolve, reject) => {
// call resolve to trigger any .then's
// call reject to "throw an error" and trigger .catch's
// Do some async task, like a network request, file system access, etc...
setTimeout(() => {
try {
resolve(2);
} catch (error) {
reject(error);
}
}, 1);
});
// Use .then to schedule a callback for when this promise resolves
promise.then(r => console.log(r)); // => 2
// Calling .then creates a new promise, can be chained like `.map` on other data structures
const newPromise = promise.then(r => r * 2);
// Notice that the resolve value of the first promise never changes
promise.then(r => console.log(r)); // => 2
newPromise.then(r => console.log(r)); // => 4
/* #endregion */
/* #region Rewriting FS example with a promise */
const fs = require('fs');
const fileContents = new Promise((resolve, reject) => {
fs.readFile('hello.txt', (err, result) => {
if (err) {
reject(err);
} else {
resolve(result.toString());
}
});
});
fileContents.then(result => {
console.log(result);
});
/* #endregion */
/* #region Implementing your own Promise */
class MyPromise {
_resolved = undefined;
_resolve = (value) => {
if (!this._resolved) {
this._resolved = value;
this.thens.forEach(fn => fn(this._resolved));
}
}
thens = [];
then(fn) {
let _resolve;
const newMyPromise = new MyPromise(resolve => {
_resolve = resolve;
});
let wrappedFn = () => {
_resolve(fn(this._resolved));
}
if (!this._resolved) {
this.thens.push(wrappedFn);
} else {
wrappedFn();
}
return newMyPromise;
}
constructor(init) {
init(this._resolve/* TODO: make these rejectable */);
}
}
const promise = new MyPromise((resolve, reject) => {
// call resolve to trigger any .then's
// call reject to "throw and error" and trigger .catch's
// Do some async task, like a network request, file system access, etc...
setTimeout(() => {
try {
resolve(2);
} catch (error) {
reject(error);
}
}, 1);
});
promise.then(r => console.log(r)); // => 2
const newPromise = promise.then(r => r * 2);
promise.then(r => console.log(r)); // => 2
newPromise.then(r => console.log(r)); // => 4
/* #endregion */
/* #region Question 1 - Promises */
// Which order do they log?
setTimeout(() => console.log("#5"), 0);
const myPromise = new Promise((resolve) => {
console.log("#1: In Promise constructor callback.")
resolve(42);
});
console.log("#2: Before myPromise.then");
myPromise.then((result) => console.log(`#3: Promise result: ${result}`));
console.log("#4: After myPromise.then");
/* #endregion */
/* #region Question 2 */
// Which order do they log?
Promise.resolve(17).then((result) => console.log(`#1: Promise result: ${result}`));
console.log("#2: After myPromise.then");
/* #endregion */
/* #region promisify */
// Callbacks suck, so they invented promisify (only in Node)
const util = require('util');
const fs = require('fs');
var promisify = util.promisify;
var readFile = promisify(fs.readFile);
const promiseResult = readFile('./hello.txt');
promiseResult
.then((result) => console.log(result.toString()))
.catch(e => {
console.log(e);
});
/* #endregion */
/* #region async/await */
// Promises suck so they invented async/await
const util = require('util');
const fs = require('fs');
var promisify = util.promisify;
var readFile = promisify(fs.readFile);
(async () => {
try {
const result = await readFile('hello.txt');
console.log(result.toString());
} catch (e) {
console.log(e);
}
})();
// Question?: What is the return value of any async function?
/* #endregion */
/* #region Question 4 */
// Which order do they log?
(async () => {
const promise = Promise.resolve();
promise.then(() => console.log('#1: Promise.then'));
console.log('#2: before await');
await promise;
console.log('#3: after await');
})();
/* #endregion */
/* #region You don't always have to `await` a promise */
(() => {
const unused = sendBeaconEventButIDontCareEnoughToBlockTheActionOfMyButton();
for (const thing of myThings) {
await doSomething(thing);
}
// vs
await Promise.all(myThings.map(thing => doSomething(thing)));
})();
/* #endregion */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment