为什么Promise.all错误?:TypeError:无法读取未定义的属性'Symbol(Symbol.iterator)'

时间:2019-12-18 18:15:16

标签: javascript node.js

我有以下控制器方法:

const org = await organisation.toJSON().name;
// The next line works fine, that's not the problem
const users = await organisation.getUsers(organisation.toJSON().id, User);
await Promise.all(users.forEach(async user => {
  await sendAccountEmail(
    user.email,
    user.surname,
    org
  );
}));

对于Promise行,我得到一个错误:

  

UnhandledPromiseRejectionWarning:TypeError:无法读取属性   不确定的'Symbol(Symbol.iterator)'

知道我的代码有什么问题吗?

2 个答案:

答案 0 :(得分:3)

您使用的Promise.all错误。该方法希望您为它提供一个填充有Promises的数组(或另一个可迭代对象),然后等待直到该数组中的所有Promises都已解决(已解决或拒绝)。您不应该遍历参数内部的数组,尤其是不要使用返回未定义的forEach,从而使您的代码等效于await Promise.all(undefined) -这样您现在就可以知道为什么会出错了,可以吗?你吗?

您应该做的是使用Array.map将用户数组转换为要等待的承诺数组:

const userPromises = users.map(user => sendAccountEmail(user.email, user.surname, org));
await Promise.all(userPromises);

答案 1 :(得分:0)

尽管您已经有了答案,但我想我会解释您所得到的实际错误,因为了解该特定错误的含义以及Promise.all()的实际工作方式非常有用。

您得到的错误是:

  

UnhandledPromiseRejectionWarning:TypeError:无法读取未定义的属性'Symbol(Symbol.iterator)'

这里有两件事。

  1. Promise.all()期望将iterable作为其参数,它可以从中获取迭代器并对其中的项目进行迭代。您的代码正在传递.forEach()的结果undefined,因此此错误的第一部分是undefined不是可迭代的,而发现此错误的方式是不会具有属性Symbol(Symbol.iterator)

  2. 此错误的第二部分是UnhandlePromiseRejectionWarning。这表明await Promise.all(...)被拒绝,您对此没有错误处理。您应该在try/catch周围加上await,或者像.catch()一样使用Promise.all().catch()。您接受的答案不能解决此编码问题。虽然修复代码可以阻止正常执行代码时出现拒绝,但是sendAccountEmail()在我看来像一个可能会失败并可能拒绝的函数。您的代码需要处理这种情况。我们实际上不能在这里提出最佳的总体错误处理策略,因为我们需要查看更大的代码上下文,以了解发生错误时应该发生的情况。但是,您需要处理所有可能的错误。