0

鉴于我正在处理表单的场景,并且我有这个验证对象

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]),
)
4

2 回答 2

3

您可以投入 aPromise.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)]
  ))
))

你绝对应该 - 循环遍历 promises 并await一个接一个地破坏它们的代码。

于 2020-05-27T10:17:06.320 回答
0

使用我编写的库有一种简单而实用的方法: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并行化使用输入调用每个提供的函数的结果的承诺。在这种情况下没有输入。我建议提供返回这些 Promises 的函数,fork而不是像我所做的那样直接提供 Promises。

于 2020-05-27T22:25:44.283 回答