我有以下控制器方法:
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)'
知道我的代码有什么问题吗?
答案 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)'
这里有两件事。
Promise.all()
期望将iterable作为其参数,它可以从中获取迭代器并对其中的项目进行迭代。您的代码正在传递.forEach()
的结果undefined
,因此此错误的第一部分是undefined
不是可迭代的,而发现此错误的方式是不会具有属性Symbol(Symbol.iterator)
。
此错误的第二部分是UnhandlePromiseRejectionWarning
。这表明await Promise.all(...)
被拒绝,您对此没有错误处理。您应该在try/catch
周围加上await
,或者像.catch()
一样使用Promise.all().catch()
。您接受的答案不能解决此编码问题。虽然修复代码可以阻止正常执行代码时出现拒绝,但是sendAccountEmail()
在我看来像一个可能会失败并可能拒绝的函数。您的代码需要处理这种情况。我们实际上不能在这里提出最佳的总体错误处理策略,因为我们需要查看更大的代码上下文,以了解发生错误时应该发生的情况。但是,您需要处理所有可能的错误。