MongoDB查询结果迭代调用API报错:userPromises非可迭代对象
遍历MongoDB记录并批量发起API调用的问题解决
问题场景
原本遍历MongoDB记录的代码可正常打印用户信息:
const usersToFollow = await userStore.find({}).limit(10); await usersToFollow.forEach(u => { console.log(`user: ${u.username}`) })
但修改为批量发起API调用的代码后无法运行,报错提示userPromises is not an iterable,代码如下:
const userPromises = usersToFollow.map(u => { console.log(`user: ${u.username}`) return twitterClient.v1.createFriendship({ user_id: u.id}) }); await Promise.all(userPromises);
原因分析
userStore.find({}).limit(10)返回的不是普通数组,而是MongoDB的游标(Cursor)对象,游标本身不支持map方法,直接调用会得到非可迭代结果,导致Promise.all报错。
解决方法
需要先将游标转换为可迭代的数组,或利用游标自身的遍历方法处理:
方法1:转换为数组后批量处理
通过toArray()将游标转为普通数组,再执行map生成Promise集合:
// 先把游标转为数组 const usersToFollow = await userStore.find({}).limit(10).toArray(); const userPromises = usersToFollow.map(u => { console.log(`user: ${u.username}`) return twitterClient.v1.createFriendship({ user_id: u.id}) }); await Promise.all(userPromises);
方法2:利用游标遍历收集Promise
如果数据量较大,不想一次性加载所有数据到内存,可通过游标自带的forEach逐个收集Promise:
const cursor = userStore.find({}).limit(10); const userPromises = []; await cursor.forEach(u => { console.log(`user: ${u.username}`) userPromises.push(twitterClient.v1.createFriendship({ user_id: u.id})); }); await Promise.all(userPromises);
链式串行调用API的实现
若需要按顺序逐个发起API请求(避免触发平台频率限制),可使用for...of循环实现串行执行:
const usersToFollow = await userStore.find({}).limit(10).toArray(); for (const u of usersToFollow) { console.log(`user: ${u.username}`); // 等待当前请求完成后再发起下一个 await twitterClient.v1.createFriendship({ user_id: u.id}); }
内容的提问来源于stack exchange,提问作者Ritzy Dev
相关产品推荐
相关产品推荐

