Home > Enterprise >  TypeScript combine multiple Promises await
TypeScript combine multiple Promises await

Time:04-14

I have basically a piece of code where I have a variable that consolidates multiple promise awaits and concat them into a single object

const traversals = (await traverseSchemas({filename:"my-validation-schema.json"}).concat([
      _.zipObject(
        ["id-1", "id-2"],
        [
          await loadSchema({
            filename: "schema-1.json"
          }),
          await loadSchema({
            filename: "schema-2.json"
          }),
        ]
      ),
    ]);  

The traverseSchemas returns an array object [{"key1":{object}}, {"key2": {object}}]

I am exploring if there is a away I can apply await at traversals level only to get all the promised fulfilled data or if there is any better way to refactor the code.

CodePudding user response:

Because no promise depends on the result of another, you can execute all of them simultaneously (in parallel) using Promise.all. This only utilizes a single await and the return ... is a purely synchronous expression combining the awaited values -

async function traversals() {
  const [validation, schema1, schema2] = await Promise.all([
    traverseSchemas({filename:"my-validation-schema.json"}),
    loadSchema({filename: "schema-1.json"}),
    loadSchema({filename: "schema-2.json"}),
  ])

  return [
    ...validation,
    _.zipObject(["id-1", "id-2"], [schema1, schema2])
  ]
}

If you have access to top-level await or this is already part of another async function, you can define const traversals = ... instead of using return -

const [validation, schema1, schema2] = await Promise.all([
  traverseSchemas({filename:"my-validation-schema.json"}),
  loadSchema({filename: "schema-1.json"}),
  loadSchema({filename: "schema-2.json"}),
])

const traversals = [
  ...validation,
  _.zipObject(["id-1", "id-2"], [schema1, schema2])
]

CodePudding user response:

There are many options.

Typically plain code is easier to understand. So I would go for something like this:

const validationSchemas = await traverseSchemas({ filename:"my-validation-schema.json" })
const schema1 = { "id-1": await loadSchema({ filename: "schema1-json" });
const schema2 = { "id-2": await loadSchema({ filename: "schema2-json" });

const traversals = [ ...fetchedSchemas, schema1, schema2 ];

If you want to parallelize awaits, you could prepare them first, then request via Promise.all and then join together:

const tasks = [
    traverseSchemas({ filename:"my-validation-schema.json" }),
    loadSchema({ filename: "schema1-json" }),
    loadSchema({ filename: "schema2-json" })
];

const [validationSchemas, schema1Value, schema2Value] = await Promise.all(tasks);

const traversals = [
    ...validationSchemas,
    { 'id-1': schema1Value },
    { 'id-2': schema2Value }
];
  • Related