在 Promise 中将项目添加到数组时遇到问题

Posted

技术标签:

【中文标题】在 Promise 中将项目添加到数组时遇到问题【英文标题】:Having issues adding items to an array within promise 【发布时间】:2020-07-08 19:25:49 【问题描述】:

我正在制作一个类似社交媒体的网站,用户可以在其中互相关注。在我的一条路线中,我想遍历当前用户关注的数组,这是一个 id 数组,找到这些用户的帖子并将它们添加到一个大数组中,然后按日期对帖子进行排序。问题是数组在帖子被添加到它之前被发送到客户端。不确定我是否需要某种异步功能或什么。

我的发帖途径

const express = require('express')
const user = require("../models/user')
const router = express.Router()

router.get("/api/:username/following/posts", (req, res) => 
    let following = [...req.user.following, req.user._id]
    let posts = [], i;
    for(i = 0; i < following.length; i++)
        User.findById(following[i]).populate("posts")
            .then(user => 
                for(let b = 0; b < user.posts.length; b++)
                    posts.push(user.posts[b])
                
            )
            .catch(err => 
                console.log(err)
            )
    
    console.log(posts) // returns []
    res.json(posts) 
)

【问题讨论】:

【参考方案1】:

您可以使用 async/await,或者您可以将 res.json 调用移至 .then

【讨论】:

因为.then 为每个关注者调用一次,这根本不起作用 是的。我没有给予足够的关注。【参考方案2】:

使用异步/等待

router.get("/api/:username/following/posts", async (req, res) => 
    const following = [...req.user.following, req.user._id]
    const posts = [];
    for(let f of following)
        const user = await User.findById(f).populate("posts");
        posts.push(...user.posts);
    
    console.log(posts)
    res.json(posts) 
)

仅使用承诺

router.get("/api/:username/following/posts", (req, res) => 
    const following = [...req.user.following, req.user._id];
    Promise.all(following.map(f => User.findBy(f).populate("posts")))
    .then(users => 
        const posts = users.map((posts) => posts).flat();
        console.log(posts);
        res.json(posts);
    );
)

主要区别在于,只有 Promises 的代码会并行调用 User.findBy,而 async/await 会依次调用它们(不用担心,promise 版本中也会维护顺序)

如果并行调用 findBy 出现问题,而您仍然不想使用 async/await,则可以这样做:

router.get("/api/:username/following/posts", (req, res) => 
    const following = [...req.user.following, req.user._id];
    Promise.all(following.reduce((p, f) => p.then(results => User.findBy(f).populate("posts").then(user => [...results, user])), Promise.resolve([])))
    .then(users => 
        const posts = users.map((posts) => posts).flat();
        console.log(posts);
        res.json(posts);
    );
)

【讨论】:

以上是关于在 Promise 中将项目添加到数组时遇到问题的主要内容,如果未能解决你的问题,请参考以下文章

在VBScript中将项目添加到数组

在 Swift 中将项目添加到 Firebase 数组而不首先观察数组

如何在 jQuery 中将项目添加到数组中?

在 Python Kivy 中将数组添加到列表视图时面临的问题

如何在 node.js 中将函数与 Promise 同步

在 Swift 中将 .plist 数据读入字典