|
/* |
|
Wherein I set out to demonstrate that even though Google V8 engine syntax includes async and Promises |
|
it is async in syntax only, and not in implementation. |
|
|
|
The code below takes async function and runs them in parallel with `Promises.all` |
|
But it is clear from the timing that it runs syncronously. |
|
*/ |
|
|
|
/* |
|
The promise returned in this function should resolve itself in 5 seconds, and running three of them |
|
in parallel should also take 5 seconds. |
|
Instead, an error is thrown as setTimeout is a `ReferenceError` and is undefined. |
|
It is expected that on the first error thrown, it stops the other two (does not throw three errors). |
|
(That setTimeout is a ReferenceError probably be the only clue we need that the stack is not async.) |
|
*/ |
|
function useSetTimeout () { |
|
const fiveSeconds = 5000; |
|
return new Promise(resolve => setTimeout(resolve, fiveSeconds)); // ReferenceError: setTimeout not defined |
|
} |
|
|
|
async function calc(i, j) { |
|
return i + j; |
|
} |
|
|
|
/* |
|
The promise returned in this function should resolve itself in about 7 seconds, and running three of them |
|
in parallel should also take about 7 seconds. |
|
Instead, it takes 24 seconds (your mileage may vary) ... as if it had to run three times syncronously |
|
(This indicates that it isn't being run in parallel like it should be.) |
|
*/ |
|
function useForLoop () { |
|
return new Promise( resolve => { |
|
let total = 0; |
|
for (let i = 0; i <= 10000; i++) { |
|
for (let j = i; j > 0; j--) { |
|
total += await calc(i + j); |
|
} |
|
} |
|
resolve("completed"); |
|
} ); |
|
} |
|
|
|
/* |
|
This function does the work of attempting to run the async functions in paraellel. |
|
*/ |
|
async function concurrency(func) { |
|
let promises = []; |
|
promises.push(func()); |
|
promises.push(func()); |
|
promises.push(func()); |
|
// Send an array of promises which should be executed |
|
let results = await Promise.all(promises); |
|
return results; |
|
} |
|
|
|
/* |
|
This function implements timing, calls `concurrency`, which hands off to the intended asyncFunction |
|
*/ |
|
function timeit (asyncFunction) { |
|
const start = new Date().getTime(); |
|
concurrency(asyncFunction).then(result => { |
|
const end = new Date().getTime(); |
|
const duration = (end - start) / 1000; |
|
Logger.log(`function ${asyncFunction.name} took ${duration} seconds to complete`); |
|
}).catch(error => { |
|
Logger.log(error); |
|
}); |
|
} |
|
|
|
/* |
|
Execute this function from the play button in the online editor |
|
*/ |
|
function entrypoint () { |
|
timeit(useSetTimeout); |
|
timeit(useForLoop); |
|
} |
|
|
Yea I was looking at the code block you have up top. The code above would work after you tag useForLoop as asyc. As of right now I am with you that using Promises has mixed value atm.