简体   繁体   中英

Await and return all resolved promise values together within an object

I have an object we'll call pages where the value for each key ( typeOne , typeTwo , etc...) is an array of objects - and a key in that object called formData is a pending Promise. I'd like to essentially update the pages object such that each formData key is the promise's resolved value.

I have successfully been able to do so by essentially mapping through each of the values in pages - however, this is slow because seems to await and resolve each type* 's array set before moving to the next set, if that makes any sense.

(async () => {
  let pages = {
    typeOne: [
      {
        formData: Promise<pending>
      },
      ...
    ],
    ...
  }
  ...
  for (type of _.keys(pages)) {
    pages[type] = await Promise.all(pages[type].map(async page => {
      page.formData = await page.formData;
      return page;
    })); 
  }
  ...
  // do stuff with pages
})()

Is there clean way to write this such that it awaits all Promises at once, then replaces the promises with the resolved values?

You need two Promise.all s; one to iterate over the keys, and another nested one to iterate over each page:

  const resolvedPages = {};
  await Promise.all(Object.entries(pages).map(([key, typeArr]) =>
    Promise.all(typeArr.map(
        // Wait for each individual Promise to resolve, then map to a new object
        ({ formData }) => formData.then(({ resolveValue }) => ({ formData: resolveValue }))
      )
      .then((resolvedArrOfObjs) => {
        resolvedPages[key] = resolvedArr;
      })
    )
  ))

No need for an iteration library.

Make sure not to implicitly create global variables, like with for (type of - that'll pollute the global scope or throw errors in strict mode.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM