DEV Community

Common Node.js mistakes in Lambda

Yan Cui on October 19, 2019

I have helped quite a few clients with their Node.js serverless projects. In doing so I have seen some recurring mistakes around async/await. ...
Collapse
 
dmh2000 profile image
david howard

const sleep = (ms) => new Promise(r => setTimeout(r, ms)); // from the linked post

[1, 2, 3].forEach(async (num) => {
await sleep(50);
console.log(num);
});
console.log('all done');

prints:
F:\projects>node x.js
Done
1
2
3

F:\projects>

I understand why 'all done' comes first, but the console.log's all print as expected. of course they come after 'all done', but the article and the link don't explain why the console.logs wouldn't work, because it appears they do. It might be because the linked article used a preproduction v 7 node where async/await/promises weren't quite working. or something.

node 10.x

Collapse
 
theburningmonk profile image
Yan Cui

Yeah, I see the same behaviour as you in Node 8, so it's possible the console.log issue is related to Node7.

But it wasn't the problem that I was hoping to highlight (my bad!), which is that it doesn't behave as you'd expect when you await sleep(50) inside an async function. It has stung me in the past where we had something along the lines of

xs.forEach(async (x) => {
  const result = await doSomething(x);
  // do something with results
})

doSomethingElseAfterAllResultsAreProcessed();

which fails because by the time doSomethingElseAfterAllResultsAreProcessed runs the results haven't actually been processed in the forEach. Once you understand the problem it's easy to see why it behaved that way, but it wasn't intuitive as the time of writing the code (which is why I actually made this mistake multiple times before I eventually "learnt the lesson").

Collapse
 
theburningmonk profile image
Yan Cui

haha, you're not alone in this - I have run into the same problem (it's not isolated to Lambda by the way) multiple times myself before it's finally carved in stone in my head. It's a systematic failure on the part of the language that it doesn't work intuitively, and unless it improves at the language level we have to (sadly) rely on memorization and building up muscle memory individually.

Collapse
 
pavelloz profile image
Paweł Kowalski

Great post! Im still guilty of some errors after all those years ;)

Collapse
 
theburningmonk profile image
Yan Cui

Thank you, I've made these mistakes before as well. That forEach thing has stung me multiple times and it was a pain to debug!

Collapse
 
fjanon profile image
Fred Janon

Why using a callback instead of an async function would be a mistake? Why wouldn't the callback work or be less efficient?

Collapse
 
theburningmonk profile image
Yan Cui

You can use callback instead of async, but probably shouldn't mix the two as it gives off the impression that you can return early before the async function's promise resolves. Which is not the case, the Lambda invocation will finish and return to the caller with a response when the async function's promise resolves at the end.