New Promise Syntax Proposal

# Jorge Téllez (6 years ago)

I would like to propose a new syntax for promises for the next ECMAScript.

It is common to define promises in the following way:

function promiseFunction() { return new Promise(resolve, reject) { resolve(someValue); }; }

In the previous example, I am declaring a function so that I can access the promise throughout.

I would like propose a simpler syntax to remove this redundancy:

promise promiseFunction(resolve, reject) { resolve(someValue); }

This will make the promise declaration easier to read in a similar fashion as the new class syntax made it easier to declare prototypes.

__ Jorge Téllez +52 1 81 2567 8257 @novohispano twitter.com/novohispano

# Isiah Meadows (6 years ago)

I'm not convinced of the need. Promises are already sufficient, and in general use, I rarely use the constructor outside of adapting callback-related code or other lower-level cases.

Also, keep in mind, most such promise-returning functions do have arguments, which this proposal seems to miss.

# Oriol _ (6 years ago)

Consider using an async function:

async function promiseFunction() {
  return someValue;
}
# Michael Rosefield (6 years ago)

Adding 'promise' as a keyword when it is certainly used as a variable name throughout many codebases is asking for trouble.

I'd also add that you could use const promiseFunction = new Promise(res, rej) { [...] };

As Isiah hinted, you can often be much more terse: const promiseFunction = Promise.resolve(resValue);

# Jonathan Barronville (6 years ago)

From the example provided, as someone who uses promises a lot, I’m not sure

I’m sold on the need for this either. Maybe you could provide some more concrete examples, Jorge?

P.S. Proposals like this are why JavaScript should’ve been a LISP ;p …

# Isiah Meadows (6 years ago)

There is Sweet.js, which addresses this issue somewhat. ;-)

# T.J. Crowder (6 years ago)

On Mon, Nov 6, 2017 at 3:23 PM, Jorge Téllez <novohispano at gmail.com> wrote:

I would like to propose a new syntax for promises for the next ECMAScript.

We already have a concise syntax for a function that returns a promise: async:

async function promiseFunction() {
    // Do work here, throw exception to reject,
    // perhaps use `await` to wait for other promises...
    return theResult;
};

More: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

-- T.J. Crowder

# Jorge Téllez (6 years ago)

Yes, I’ll be happy to provide a concrete example.

Let’s say I am creating a CLI using readline.

const readline  = require('readline');
const interface = readline.createInterface({
  input:  process.stdin,
  output: process.stdout
});

async function run() {
  var name = '';
  var base = 0;

  console.log('** Bienvenido al Calculador de Área **');

  name = await requestInput(‘What’s your name?\n');
  console.log(`Hello, ${name}!`);
}

function requestInput(question) {
  return new Promise(function(resolve) {
    interface.question(question, function(input) {
      resolve(input);
    })
  })
}

run();

Instead of defining a wrapper function that returns a promise, I would like to define the promise at the same time like this:

const readline  = require('readline');
const interface = readline.createInterface({
  input:  process.stdin,
  output: process.stdout
});

async function run() {
  console.log('** Bienvenido al Calculador de Área **');

  const name = await requestInput(‘What’s your name?\n');
  console.log(`Hello, ${name}!`);
}

promise requestInput(resolve, reject, question) {
  interface.question(question, function(input) {
    resolve(input);
  })
}

run();

__ Jorge Téllez +52 1 81 2567 8257 @novohispano twitter.com/novohispano

# T.J. Crowder (6 years ago)

On Mon, Nov 6, 2017 at 3:39 PM, Jorge Téllez <novohispano at gmail.com> wrote:

Yes, I’ll be happy to provide a concrete example.

Very useful example!

In that scenario I'd convert to promises early, by promisifying the interface.question function once (using util.promisify or roll-your-own if needed), and then using the promisified version throughout (which lets you use async functions).

-- T.J. Crowder

# Jonathan Barronville (6 years ago)

@T.J. Crowder: Interestingly, in this case, it looks like the readline module’s @question(…) API doesn’t even use the usual Node.js-style callback, which is what util.promisify expects …

# Mat At Bread (6 years ago)

I proposed an enhanced definition for async return and async throw to address this issue in tc39/ecmascript-asyncawait#38 – it didn’t get accepted, however it is implemented in rodent (see MatAtBread/nodent#exiting-async-functions-from-callbacks)

Using it would produce an async function like:



async function requestInput(question) {
    interface.question(question, function(input) {
        async return input ;
    });
}

# T.J. Crowder (6 years ago)

On Mon, Nov 6, 2017 at 3:57 PM, Jonathan Barronville <jonathan at belairlabs.com> wrote:

@T.J. Crowder: Interestingly, in this case, it looks like the readline module’s @question(…) API doesn’t even use the usual Node.js-style callback, which is what util.promisify expects …

Yeah, that's why I included the "or roll-your-own if needed" bit. :-)

-- T.J. Crowder

# Isiah Meadows (6 years ago)

You may find it interesting that Node.js created a private symbol to allow that and others (like fs.exists) to be promisified similarly, even though they don't follow the standard convention.

# Augusto Moura (6 years ago)

Using arrow functions it doesn't look so verbose

function requestInput(question) {
  return new Promise(function(resolve) {
    interface.question(question, function(input) {
      resolve(input);
    })
  })
}

can be written as:

const requestInput = question => new Promise((resolve) => {
  interface.question(question, resolve);
  // You can wrap resolve in a `unary` helper if more than 1 argument is problematic
});

I don't see a problem with verbosity here

# Pranay Prakash (6 years ago)

Lot of good ideas mentioned in this thread, and I think in general, the async/await pattern helps to make code like this more terse.

Rather than inventing new syntax like:

promise promiseFunction(resolve, reject, …args) {  // call to reject() or
resolve()
}
…

the existing way of implementing this is:

async function promiseFunction(…args) {  // return something (to resolve) or throw an error (to reject) } … We already have the latter, and it is cleaner IMO Cheers,Pranay

On Mon, Nov 6, 2017 1:05 PM, Augusto Moura augusto.borgesm at gmail.com wrote: Using arrow functions it doesn't seems so verbose

function requestInput(question) return new Promise(function(resolve) {   
interface.question(question, function(input) {      resolve(input);    })  })}
```can be written as:
```js
const requestInput = question => new Promise((resolve) => {

interface.question(question, resolve); // You can wrap resolve in a `unary`
helper if more than 1 argument is problematic
});

I don't see a problem with verbosity