You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何等待this.getStock执行完成后再发送接口响应

问题根因

返回空数组是JavaScript异步执行时序导致的:getStock是返回Promise的异步方法,for循环执行时只会触发异步任务、不会阻塞等待任务返回,循环结束后会立刻执行后续的res.send逻辑,此时所有getStock的查询回调还没执行,reply数组还没被写入数据,自然返回空。
另外原有代码res.send(reply).sendStatus(200)存在写法错误:res.send执行后已经完成响应发送,后续链式调用sendStatus会触发重复响应报错。

修复方案

核心是等待所有库存查询的异步任务全部执行完成后,再发送响应,两种常用写法可选:

async/await 写法(推荐,可读性更高)

async stock(@Req() req: Request, @Res() res: Response, next: NextFunction) {
    const parts = req.body.cxml.credentials[0].partslist[0]
    // 批量构造所有库存查询的Promise任务
    const stockQueryTasks = parts.part.map(partItem => {
        const partNumber = JSON.stringify(partItem.partnumber[0]).replace(/['"]+/g, '')
        return this.getStock(partNumber)
    })
    // 等待所有查询完成,直接拿到顺序匹配的结果数组
    const reply: Stock[] = await Promise.all(stockQueryTasks)
    console.log(reply)
    // 正确设置状态码并发送响应
    res.status(200).send(reply)
}

Promise then 链式写法

如果不使用async/await语法,可直接收集所有Promise后统一等待回调:

stock(@Req() req: Request, @Res() res: Response, next: NextFunction) {
    const parts = req.body.cxml.credentials[0].partslist[0]
    const stockQueryTasks = parts.part.map(partItem => {
        const partNumber = JSON.stringify(partItem.partnumber[0]).replace(/['"]+/g, '')
        return this.getStock(partNumber)
    })
    Promise.all(stockQueryTasks)
        .then((reply: Stock[]) => {
            console.log(reply)
            res.status(200).send(reply)
        })
        .catch(err => {
            // 必须加错误兜底,避免查询失败时接口挂死无响应
            next(err)
        })
}
注意事项
  • 单个HTTP请求只能发送一次响应,需要同时设置状态码和响应内容时,使用res.status(状态码).send(响应内容)的写法,不要链式调用多个响应方法
  • 多个并行异步任务不要依赖循环内手动push结果的方式收集数据,Promise.all除了自动等待所有任务完成,还能保证返回结果的顺序和传入任务的顺序一一对应,避免因为接口返回速度差异导致结果顺序错乱
  • 所有异步逻辑必须加错误捕获,避免单个查询失败导致整个接口超时无响应

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 12:39:15