await setTimeout in async functions
Why not using fill setTimeout API, also granting you args are those passed
at the invocation time and no possible mutation capable of affecting computeResult
could happen later on?
const asyncFunc = (...args) => new Promise((resolve) => {
setTimeout(resolve, 1000, computeResult(...args));
});
Otherwise you can always do the following
const asyncFunc = (...args) =>
new Promise(r => setTimeout(r, 1000))
.then(() => computeResult(...args));
isn't it?
On Tue, Feb 28, 2017 at 7:47 PM, Andrea Giammarchi < andrea.giammarchi at gmail.com> wrote:
Why not using fill setTimeout API, also granting you args are those passed at the invocation time and no possible mutation capable of affecting
computeResult
could happen later on?
const asyncFunc = (...args) => new Promise((resolve) => { setTimeout(resolve, 1000, computeResult(...args)); });
That would call computeReult
before the timeout fired, whereas
apparently it should be after the delay.
Your second one, though, is nice and simple. Using Jérémy's delay
, it
looks like this:
const asyncFunc = (...args) =>
delay(1000).then(() => computeResult(...args));
-- T.J. Crowder
In the first example, I haven't written this by accident:
also granting you args are those passed at the invocation time and no
possible mutation capable of affecting computeResult
could happen later
on?
which is why I've shown both examples, the before setTimeout(resolve, 1000, computeResult(...args));
and the after ;-)
On Tue, Feb 28, 2017 at 8:14 PM, Andrea Giammarchi < andrea.giammarchi at gmail.com> wrote:
In the first example, I haven't written this by accident:
also granting you args are those passed at the invocation time and no possible mutation capable of affecting
computeResult
could happen later on?
Okay. With respect, that sentence is really unclear, esp. given the
context that it was obvious from the example that it's important that
computeResult
isn't called until after the delay. But we're all on the
same page now.
-- T.J. Crowder
it was obvious from the example that it's important that
computeResult
isn't called until after the delay
I was just underlying possible side effects. TBH, I don't even know why forcing a delay to an async function would be needed but yeah, definitively on the same page.
I am also a bit against underpowered patterns, like a delay(1000) over setTimeout since the latter one can be canceled, a delay(1000) without cancelable Promises is a curse, IMO
¯_(ツ)_/¯
I don't even know why forcing a delay to an async function would be needed
In my opinion, for the same reasons calling setTimeout
would have been needed: batching several calls together for a request, simulating i/o latency, delaying the rest of an expensive computation later in the event loop, racing with another operation for a timeout, …
I tend to see setTimeout
as an old function, not meant to work well with recent ES features (Promises and async functions), having disadvantages (for example, error handling), and AFAIK not standard.
On the other hand, it’s easy to write or find a Promise-returning delay. And there is the cancellation issue (but I have the intuition that a “delay function” now will be compatible with any “cancellation solution” later).
I believe that, at some point, the “delaying” feature should be reviewed. Maybe not now.
AFAIK not standard.
FYI it's standard for the DOM world.
www.w3.org/TR/2011/WD-html5-20110525/timers.html#timers
About cancelability, if the purpose is to delay stressful operations, I would definitively like to cancel that whenever is needed ;-)
A generic Promise based delay(ms)
seems to be trivial enough I don't
think specs should be bothered.
I mean, this is all it takes, right?
const delay = ms => new Promise(r => setTimeout(r, ms));
Let's take a simple asynchronous function
const asyncFunc = (...args) => new Promise((resolve) => { setTimeout(() => resolve(computeResult(...args)), 1000); });
One problem in this example is that any error thrown by
computeResult
will not be correctly handled. This can be solved with anasync
function:const delay = (duration) => new Promise(resolve => setTimeout(resolve, duration)); const asyncFunc = async (...args) => { await delay(1000); return computeResult(...args); };
It's always better to handle errors. So I would not be surprised if a similar pattern become favoured over the use of
setTimeout
, when writing and learning asynchronous functions.Writing a
delay
function is easy. But a standardised statement (await*delay
,await.nextTick
or whatever name or syntax) would highlight these patterns. It would also be an opportunity to standardisesetTimeout
,setImmediate
and such, without risking incompatibilities (I've seen that point reported in a recent email). Cancellation would probably be a sensible point, but it may also be left to a more global solution about cancellingasync
functions.I’ve found some old discussions about a Promise-returning delay function, showing that the (lack of?) concept of event-loop in ES would be a problem.
await
keyword.Is it worth discussing again, in the context of
async
functions?.