examples/javascript/async/async.js

73 lines
1.8 KiB
JavaScript

/**
* log a message with an iso datetime
* @param {*} msg msg to log
*/
const log = (msg) => {
console.log(msg, new Date().toISOString());
};
/**
* sleep for a certain amount of ms
* @param {*} ms ms to sleep
*/
const sleep = (ms) => {
return new Promise((resolve) => setTimeout(resolve, ms));
};
/**
* "asyncForEach" method on every array, allowing for async functionality on any array
*/
if (!Array.prototype.asyncForEach) {
Array.prototype.asyncForEach = async function (func) {
"use strict";
if (this == null) {
throw new TypeError(
"Array.prototype.asyncForEach called on null or undefined"
);
}
if (typeof func !== "function") {
throw new TypeError();
}
var t = Object(this);
return await Promise.allSettled(
t.map(async (item) => {
return await func(item);
})
);
};
}
// array is not in order, this will be used to test
const items = [200, 1000, 400, 300];
// starting test
log("Starting async test");
// because of the sleep we expect the responses from small -> large
items.asyncForEach(async (item) => {
await sleep(item);
log(item);
});
// because the previous foreach is async we expect this to run immediately.
log("after async foreach (or before? because async..)");
async function testWithAwait() {
await items.asyncForEach(async (item) => {
// this will sleep for whatever the largest amount in items is + currentItem.
// this will make sure test items are displayed AFTER the first batch of items.
// this doesn't impact the result because the code IN the foreach will still run async (just with a delayed console.log)
await sleep(Math.max(...items) + item);
log(`Async with wait: ${item}`);
});
// because of the await on line 60 this will only run AFTER the async foreach has been handled
log("after testWithAwait");
}
testWithAwait();