ES8 async function expression instantly called

I did not see these constructs used a lot, but I found that I wrote them to use async / wait in functions that usually do not return a promise, for example

chan.consume(queue, (msg) => { this.pendingMsgs++; // executed immediately (async () => { await this.handleMessage(msg); this.pendingMsgs--; if (cancelled && this.pendingMsgs === 0) { await chan.close(); await this.amqpConnectionPool.release(conn); } })(); }); 

Unlike

 chan.consume(queue, async (msg) => { // external lib does not expect a return value from this callback this.pendingMsgs++; // executed in promise context(?) await this.handleMessage(msg); this.pendingMsgs--; if (cancelled && this.pendingMsgs === 0) { await chan.close(); await this.amqpConnectionPool.release(conn); } }); 

or

 chan.consume(queue, (msg) => { this.pendingMsgs++; // no await - excess function decls & nesting this.handleMessage(msg).then(() => { this.pendingMsgs--; if (cancelled && this.pendingMsgs === 0) { chan.close().then(() => { this.amqpConnectionPool.release(conn); }); } }); }); 

Is this a "thing"? Are there any pitfalls here that I should know about? What is the low efficiency of using async / await in such situations?

+7
source share
1 answer

Is this a "thing"?

Yes. From time to time it appears, for example. here . They are known as IIAFEs :-)
If you want to focus on the arrow, you can also name them IIAAFs.

Are there any pitfalls here that I should know about?

Whenever you call the promise return function and do not return the result to another place, you are responsible for your promise - this means that you have to handle errors. Thus, the template should generally look like

 (async () => { … })().catch(err => { console.error(err); }); 

if you do not want to worry about events with an unhandled failure.

What is the low efficiency of using async / await in such situations?

Not much compared to the then version. However, you say: “the external library does not expect to return from this callback”, which may hint at the incompatibility of the library with asynchronous callbacks, so be careful what you do when. It may also depend on exceptions that are thrown synchronously from the callback, so it all depends on what the library expects here (and if there are no expectations, can this change in the future). You do not need future incompatibilities in case the library starts to treat promises return values ​​on purpose.

However, I would recommend a second template that directly passes the async function directly as a callback due to better readability. If you want to avoid returning the promise to the library, create a helper function that completes the callback:

 function toVoid(fn) { return (...args) => void fn(...args); } function promiseToVoid(fn) { return (...args) => void fn(...args).catch(console.error); } 

which you can use as follows:

 chan.consume(queue, toVoid(async (msg) => { … // use `await` freely })); 
+9
source

Source: https://habr.com/ru/post/1260147/


All Articles