Small little bug with async/await (not a huge priority)

We have a few helper functions that take in an array of thunks/chunks and return promises. They work well, but with the async/await syntax, i’m not able to inline it like I was hoping i’d be able to. It’s not a huge deal, because you can create a new function as a work around, but I thought i’d show you an example. The async tag is ommitted from the javascript compiled code and is a run time error even though in rescript everything compiles correctly.

Broken code w/ run time exception:

let doThings = (chunks: array<unit => promise<'a>>): promise<array<'a>> => {
  chunks->Array.map(c => c())->Js.Promise2.all
}

let run = async () => {
  doThings(
    ["0", "1"]->Js.Array2.map(async number => {
      async () => {
        Js.log2("number in here!", number)

        await Js.Promise2.resolve()

        Js.log("more going on.....")
      }
    }),
  )
}

run()

The focus is this part: async () => {. You’d expect the JS outputted code to have the async flag as well, but instead this is what the compiled code looks like:

// Generated by ReScript, PLEASE EDIT WITH CARE
'use strict';

var Curry = require("rescript/lib/js/curry.js");
var Belt_Array = require("rescript/lib/js/belt_Array.js");

function doThings(chunks) {
  return Promise.all(Belt_Array.map(chunks, (function (c) {
                    return Curry._1(c, undefined);
                  })));
}

async function run(param) {
  return doThings([
                "0",
                "1"
              ].map(function (number) {
                  return function (param) {
                    console.log("number in here!", number);
                    await Promise.resolve(undefined);
                    console.log("more going on.....");
                  };
                }));
}

run(undefined);

exports.doThings = doThings;
exports.run = run;
/*  Not a pure module */

You can see right here: return function (param) { it’s missing the flag async, which would be like: return async function (param) {. It was strange since rescript was compiling and everything seemed to have worked.

Anyways, the workaround is simply breaking it out into it’s own function like so:

let doThings = (chunks: array<unit => promise<'a>>): promise<array<'a>> => {
  chunks->Array.map(c => c())->Js.Promise2.all
}

let handleInside = async number => {
  Js.log2("number in here!", number)

  await Js.Promise2.resolve()

  Js.log("more going on.....")
}

let run = async () => {
  doThings(
    ["0", "1"]->Js.Array2.map(number => {
      () => handleInside(number)
    }),
  )
}

run()

This then compiles correctly and everything works. Here is the compiled code:

// Generated by ReScript, PLEASE EDIT WITH CARE
'use strict';

var Curry = require("rescript/lib/js/curry.js");
var Belt_Array = require("rescript/lib/js/belt_Array.js");

function doThings(chunks) {
  return Promise.all(Belt_Array.map(chunks, (function (c) {
                    return Curry._1(c, undefined);
                  })));
}

async function handleInside(number) {
  console.log("number in here!", number);
  await Promise.resolve(undefined);
  console.log("more going on.....");
}

async function run(param) {
  return doThings([
                "0",
                "1"
              ].map(function (number) {
                  return function (param) {
                    return handleInside(number);
                  };
                }));
}

run(undefined);

exports.doThings = doThings;
exports.handleInside = handleInside;
exports.run = run;
/*  Not a pure module */

Anyways, not a huge deal, but I figured I should share this in case any one runs into this problem, or someone would like to fix the problem.

Thank you!

2 Likes

Can you try the latest compiler from the playground (11 alpha) and if still a problem open an issue in the compiler repo?

1 Like

Thank you! I appreciate it. I tested it on v11.0.0-alpha.5 and the issue has been fixed! :smiley: :clap: :clap:

1 Like