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

如何用回调机制在嵌套for循环完成后返回result数组?

问题描述

现有如下代码:

const result = [];
for(i=0; i < 5; i++){
    for(j=0; j<3; j++){
        s3Service.getS3Content(key, bucket, (err, res)=>{
            
            if(err){
                console.log("error occurred !");
                result.push({msg:`error occurred for ${key}`})

            }
            
            if(res){
                result.push(res);
            }
            
        })
    }
}

如何在所有内外循环迭代完成后返回result?

我知道通过promise...then或async...await可以轻松解决,但出于某些原因,我希望仅通过回调机制实现。有没有简便的回调写法?

附s3Service.js代码:

const getS3Content = (key, bucketName, cb) => {
  S3.getObject({ Bucket: bucketName, Key: key }, (err, result) => {
    if (err) {
      console.log("error occured in getS3Content", err);
      cb(err);
    }

    if (result) {
      cb(null, result);
    }
  })
}
回调实现方案

可以通过计数器跟踪异步任务完成状态的方式实现,核心思路是统计所有异步请求的总数,每完成一个请求就将计数器加1,当计数器等于总请求数时,触发最终的回调返回结果。

修改后的代码示例

const result = [];
// 计算总异步任务数:5次外循环 × 3次内循环
const totalTasks = 5 * 3;
let completedTasks = 0;

// 定义所有任务完成后的回调函数,用于处理最终结果
function handleFinalResult() {
  // 此处可根据需求返回或处理result,比如传递给上层逻辑
  console.log("所有请求完成", result);
}

// 循环添加异步任务,注意用let声明循环变量避免闭包污染
for(let i=0; i < 5; i++){
    for(let j=0; j<3; j++){
        s3Service.getS3Content(key, bucket, (err, res)=>{
            if(err){
                console.log("error occurred !");
                result.push({msg:`error occurred for ${key}`});
            } else if(res){
                result.push(res);
            }
            
            // 每完成一个请求,计数器加1
            completedTasks++;
            // 检查是否所有任务都已完成
            if(completedTasks === totalTasks) {
                handleFinalResult();
            }
        })
    }
}

补充优化建议

原s3Service.getS3Content存在重复调用回调的风险(当err存在时,调用cb(err)后仍会执行if(result)分支),建议修改为:

const getS3Content = (key, bucketName, cb) => {
  S3.getObject({ Bucket: bucketName, Key: key }, (err, result) => {
    if (err) {
      console.log("error occured in getS3Content", err);
      return cb(err); // 加return终止后续逻辑,避免重复调用回调
    }
    cb(null, result); // err不存在时直接返回结果
  })
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 00:42:30