You need to enable JavaScript to run this app. Strapi中map遍历调用异步查询返回Pending Promise的问题求助
优惠活动
大模型
产品
解决方案
定价
更多

Strapi中map遍历调用异步查询返回Pending Promise的问题求助

问题根源定位

你打印的books始终是pending状态Promise,和getBooks内部的返回写法关系不大,核心问题出在调用环节:

  • 你在map的同步回调里调用this.getBooks(data.id)时,没有加await。同步逻辑执行到console.log这一行时,数据库查询的异步操作才刚被发起,根本还没拿到结果,自然只能拿到还没走完流程的pending Promise对象
  • 你修改getBooks时额外包裹的Promise.resolve(books)属于完全冗余的代码,对解决问题没有任何帮助。

补充说明:async函数本身的返回值就会被自动包装成Promise对象,当函数内部的异步操作执行完成后,这个Promise会自动转为已完成状态。不管你是直接return数据库查询结果,还是先await拿到结果再手动Promise.resolve返回,最终对外暴露的行为完全没有区别。

正确实现方式

针对Strapi接口处理的通用场景(需要等所有关联数据查询完成后,再组装成完整的响应返回给前端),可以用Promise.all配合异步map回调的写法,完整修改后的可运行代码如下:

async search(ctx) {
    const authors = [
        {
            id: 1,
            name: "author 1"
        },
        {
            id: 2,
            name: "author 2"
        },
    ]

    // 收集所有作者关联的书籍查询Promise,统一等待全部执行完成
    const authorListWithBooks = await Promise.all(
        // map的回调必须声明为async,才能在内部使用await语法
        authors.map(async (data) => {
            // 必须在调用getBooks的位置加await,才能拿到真实的数据库查询结果
            const books = await this.getBooks(data.id)
            console.log(books) // 这里会正常打印完整的书籍查询数组

            // 可按需把查询到的books挂载到作者对象上,做后续逻辑处理
            return {
                ...data,
                books
            }
        })
    )

    // 所有数据查询完成后,再正常返回接口响应
    ctx.body = authorListWithBooks
},

// 不需要额外包裹Promise.resolve,保留最简洁的写法即可
getBooks: async function (authorId) {
    return strapi.query('books').find({ userId: authorId })
}
关键注意事项
  • Array.prototype.map是同步执行方法,本身不会等待内部的异步操作走完。如果不配合Promise.all收集所有Promise并统一await,外层的接口逻辑会提前执行,不等异步查询完成就返回响应,很容易出现响应数据缺失的问题
  • 只要是调用async函数,想要拿到最终的解析值,就必须在调用位置加await,否则无论被调用的async函数内部写的多么复杂,你拿到的永远是当前未完成的Promise实例
  • 不要在async函数的返回值位置手动包裹Promise.resolve,这类写法没有任何实际作用,反而会增加无意义的代码层级

内容的提问来源于stack exchange,提问作者Emerald

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.02 03:45:05