Symbol.await proposal
Jamie
me at thejameskyle.com
Mon Jun 22 20:13:19 UTC 2020
One of the common refactorings I do is:
let file1 = await readFile(filename1)
let file2 = await readFile(filename2)
// to
let [file1, file2] = await Promise.all([
readFile(filename1),
readFile(filename2),
])
I would be very confused if refactoring it in this way made my code break
because of some implicit behavior around `await` specifically.
I have seen some APIs that switch to promises when a callback argument is
not provided. Is this not a sufficient solution?
On Mon, Jun 22, 2020 at 12:22 PM James M Snell <jasnell at gmail.com> wrote:
> For many legacy code bases that are based on callbacks mechanisms like
> node.js' promisify function are required to help facilitate the transition
> from callback centric code to Promise-centric. A lot of the time, these can
> follow straightforward rules without requiring customization. However, at
> other times it is necessary for user code to provide custom implementations
> of the Promise-version of the function.
>
> In Node.js, we accomplish this by allowing a function to have a symbol
> attached whose value is an alternative function that is returned by the
> promisify function
>
> For instance,
>
> function myFunction(foo, bar, callback) {
> callback(null, foo, bar);
> }
> myFunction[util.customPromisifySymbol] = async function(foo, bar) {
> return [foo, bar];
> }
>
> const { promisify } = require('util');
> const mine = promisify(myFunction);
> (async () => console.log(await mine('a','b')))();
>
> As a convenience built into the language, it would be nice to be able to
> short-circuit the need to call promisify with a special language-level
> Symbol used specifically for this purpose:
>
> function myFunction(foo, bar, callback) {
> callback(null, foo, bar);
> }
> myFunction[Symbol.await] = async function(foo, bar) {
> return [foo, bar];
> }
>
> (async () => console.log(await myFunction('a','b')))();
>
> The idea here is that if the function being awaited has the [Symbol.await]
> property whose value is a function, then that function is called when the
> await keyword is used. That is,
>
> myFunction('a', 'b', callback); // Invokes myFunction directly
> await myFunction('a', 'b'); // Invokes myFunction[Symbol.await]
>
> if the Symbol.await property is not set or is not callable, then it would
> fallback to default behavior.
>
> Automatic handling of this binding should also happen but has some
> technical detail to work out:
>
> const obj = {
> a: 1,
> foo() {}
> };
> obj.foo[Symbol.await] = async function() {
> return this.a;
> }
> await obj.foo(); // Calls await obj.foo[Symbol.await] with bound this
>
> This approach would make it far easier for legacy code bases to make the
> transition to async/await syntax while maintaining legacy compat.
>
> Before writing up a formal proposal, I wanted to solicit some feedback on
> this approach to see what folks thought.
>
> - James
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20200622/6ce045c7/attachment.html>
More information about the es-discuss
mailing list