12 ms·
This is huge! Finally no more need to use IIFE's for top level awaits
by miguelmota 7y ago
This is huge! Finally no more need to use IIFE's for top level awaits
- danappelxx 7y agoWhat is an IIFE?
- carreau 7y agoImmediately Invoked Function Expression: (function () { statements })();
- CryoLogic 7y agoImmediately invoked function expression - aka an anonymous function that executes as it is interpreted. (function() { console.log('test'); })(); In old versions of JavaScript, variables had to be scoped to the nearest function (rather than the nearest block) so IIFE where often used for namespacing: var $ = (function() { this.version = '1.2.3'; })(); $.version; // 1.2.3 This worked because the function would be immediately invoked upon interpretation, scoping it's contents to itself (aliased by the variable name).
- furgooswft13 7y agoHate to be a wet blanket, but that second code sample won't work. The function doesn't return anything so $ === undefined. Even if it did, this in that context is bound to the global object, so is the same as setting a variable without var or let. A proper example of IIFE for lexical scoping would be something like this: var numbers = ""; (function(){ for (var i=0; i<5; i++) { numbers += i + " "; } })(); console.log(i) //undefined Nowadays of course you could just use let instead of var Your code snippet would kind of work as expected if used as a constructor. As in: var $ = function() { this.version = '1.2.3'; }; var obj = new $; console.log(obj.version); //1.2.3 Of course that is not a IIFE. Ah...brings me back to my SO days...
- momokoko 7y agoHate to dry off the blanket but they just forgot the `new` keyword for `this` ;) var $ = new (function() { this.version = '1.2.3'; })(); console.log($.version); // '1.2.3' EDIT: Or if you really want to abuse the spec var $ = (function() { if (!(this instanceof arguments.callee)) return new arguments.callee(); this.version = '1.2.3' })(); console.log($.version); // '1.2.3'
- furgooswft13 7y agolol. But yes, I do really want to abuse the spec. You could also do this: var $ = (function(){ this.version = '1.2.3'; return this; }).call({}) console.log($.version); //1.2.3 But that's not quite as ugly so I guess I lose some points.
- 11235813213455 7y agohe should have said IIAFE actually (immediately-invoked-async-function-expression) (async () => { console.log(await 'hello world') })()
- anonytrary 7y agoAll async functions are functions, so not really.
- adrianpike 7y agoImmediately Invoked Function Expression; (function() { alert('swiggity swooty'); })();
- 52-6F-62 7y agoThis one got my vote just for swiggity swooty. Swiggity swooty, indeed.
- alexanderdmitri 7y agoAlso, I believe TypeScript uses these to transpile classes with public and private properties/methods (can't verify that's still case atm). It's a really neat pattern imo, I remember it fondly from my JS heavy days :)
- munchbunny 7y agoIt's a useful pattern that I used a lot, though I don't know if I would agree that it's neat. I definitely prefer the explicit annotations or even the python underscore convention.
- Zarel 7y agoNo, while this is sometimes used for private properties/methods, TypeScript never used it. TypeScript's private properties/methods are just compile-time errors, they're still public in the generated code.
- alexanderdmitri 7y agoYou're right[0], which is weird because they got most of the way there. I guess I just assumed since they were leveraging IIFEs this would be a natural use case. I'd be interested in knowing why they didn't actually. According to this[1] exchange on Stack Overflow, the IIFE is used by TypeScript because of other scoping issues (specifically protecting class properties before instantiation and defining interfaces). [0] https://yakovfain.com/2015/06/30/the-private-in-typescript-is-kinda-private/ https://yakovfain.com/2015/06/30/the-private-in-typescript-i... [1] https://stackoverflow.com/questions/56086411/why-does-typescript-pack-a-class-in-an-iife https://stackoverflow.com/questions/56086411/why-does-typesc...
- tlrobinson 7y agoAn easily Googleable acronym.
- megous 7y agoIt's nice, I guess, but huge? Instead of: async function main() { // code } main().catch(console.error); I'll be maybe writing: try { // code } catch (ex) { console.error(ex); } Hrm?
- casret 7y agoOne thing that has bitten me is when you are using vm.run* and friends, it's impossible to get a result of it if you need to use async calls. Hopefully this solves that case. There is also the original use case that the original proposal of needing to do async calls when during module loading.
- mattwad 7y agoI think the boon here will be for scripts that run once. Say I just want to query a few tables. Now, I no longer need a `main()` wrapper: const result = await db.events.find(); console.log(result); That's my whole script
- james-mcelwain 7y agoOr my preferred (gross) version: void async function main() { // code }()
- elyobo 7y agoMine all tend to look like (async () => { // code })().catch(console.error)
- jraph 7y agoWow, I had completely forgotten the existence of void in JavaScript. Why is it needed here? To force an expression without using the parentheses? Edit: Yes, it seems so, and this usage with functions is explicitly documented there: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/void https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
- 7y ago
- paulddraper 7y agoThough it goes even beyond that. It not only works for the main entrypoint module, but all other modules as well. Though I can say I've ever encountered a reason to have that....
- deleted 7y ago[deleted]
- nilkanthjp 7y agoSeems convenient. Though I've never thought of top-level async as the killer feature I've been waiting for out of V8. Unless I'm missing something about what this enables...