сопоставить объект, в котором есть обещания, функционально в JS - PullRequest
0 голосов
/ 27 мая 2020

Учитывая сценарий, в котором я работаю над формой, и у меня есть этот объект проверки

const errors = {
  username: ['minLength', Promise<string>, Promise<string>],
  password: [Promise<string>, Promise<string>]
}
// I need to convert the object to below
const errors = {
  username: ['minLength', string, string],
  password: [string, string]
}

Все обещания будут выполнены в будущем, поэтому я натолкнулся на эту идею:

;(async function () {
    for (const key in errors) {
      if (errors.hasOwnProperty(key)) {
        errors[key] = (await Promise.all(errors[key])).filter(Boolean)
      }
    }
    callback(errors)
  })()

Есть ли более функциональный способ сделать это?

// So far I know the most elegant way to map an object
// But won't work in this scenario
const newObj = Object.fromEntries(
  Object.entries(obj).map(([k, v]) => [k, v * v]),
)

Ответы [ 2 ]

3 голосов
/ 27 мая 2020

Вы можете добавить Promise.all, чтобы эта работа работала:

Promise.all(Object.entries(obj).map(([key, values]) =>
  Promise.all(values).then(results => [key, results.filter(Boolean)])
).then(Object.fromEntries).then(errors => {
  console.log(errors);
})

или async / await:

console.log(Object.fromEntries(
  await Promise.all(Object.entries(obj).map(async ([key, values]) =>
    [key, (await Promise.all(values)).filter(Boolean)]
  ))
))

И вам определенно следует - код, который перебирает обещания и await выводит их одно за другим не работает .

0 голосов
/ 28 мая 2020

Существует простой и функциональный способ сделать это с использованием библиотеки, которую я написал: rubico .

const { fork } = require('rubico')

const getErrors = fork({
  username: fork([
    () => 'minLength',
    () => Promise<string>,
    () => Promise<string>,
  ]),
  password: fork([
    () => Promise<string>,
    () => Promise<string>,
  ]),
})

const errors = await getErrors() /* => {
  username: ['minLength', string, string],
  password: [string, string],
} */

fork распараллеливает обещания, которые являются результатом вызова каждой предоставленной функции со входом. В этом случае ввод отсутствует. Я рекомендую предоставить функции, которые возвращают эти обещания, в fork вместо того, чтобы предоставлять обещания напрямую, как это сделал я.

...