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

如何在循环/Map中异步执行Fetch并等待结果更新数组

解决Tumblr视频帖子异步获取Vimeo缩略图的问题

核心问题就是异步操作未完成时就把对象塞进了新数组,Fetch返回的Promise还没resolve,video_thumbnail_id自然是空的。以下是两种可行的解决方案,都是基于正确等待异步请求完成后再生成目标对象:

方案1:for...of循环+async/await(直观易调试)

这种方式逐个处理帖子,适合需要严格顺序或者调试单个请求的场景:

// 假设你的Tumblr帖子数组为tumblrPosts
async function processVideoPosts() {
  const processedPosts = [];
  
  for (const post of tumblrPosts) {
    // 跳过非视频类型的帖子
    if (post.type !== 'video') {
      processedPosts.push({...post, video_thumbnail_id: null});
      continue;
    }
    
    // 从帖子body提取Vimeo视频ID(正则需根据实际内容调整)
    const vimeoIdMatch = post.body.match(/vimeo\.com\/(\d+)/);
    if (!vimeoIdMatch) {
      processedPosts.push({...post, video_thumbnail_id: null});
      continue;
    }
    const vimeoId = vimeoIdMatch[1];
    
    try {
      // 调用Vimeo API获取视频信息,替换为你的授权token
      const response = await fetch(`https://api.vimeo.com/videos/${vimeoId}`, {
        headers: {
          'Authorization': 'Bearer YOUR_VIMEO_ACCESS_TOKEN'
        }
      });
      
      if (!response.ok) {
        throw new Error(`Vimeo API请求失败,状态码:${response.status}`);
      }
      
      const videoData = await response.json();
      // 从API返回数据中提取缩略图ID(字段需根据Vimeo API实际返回调整)
      const thumbnailId = videoData.pictures?.sizes?.[2]?.uri?.split('/').pop() || null;
      
      // 等待请求完成后,再将带缩略图ID的对象推入数组
      processedPosts.push({
        ...post,
        video_thumbnail_id: thumbnailId
      });
    } catch (err) {
      console.error(`处理Vimeo视频ID ${vimeoId} 时出错:`, err);
      // 出错时仍推入对象,避免遗漏帖子
      processedPosts.push({...post, video_thumbnail_id: null});
    }
  }
  
  return processedPosts;
}

// 调用处理函数,获取结果
processVideoPosts().then(processedPosts => {
  console.log('处理完成的帖子数组:', processedPosts);
  // 这里执行后续业务逻辑
});

方案2:Promise.all批量处理(并行请求,效率更高)

如果帖子数量较多,用Promise.all并行发起请求能提升处理速度:

async function processVideoPosts() {
  // 为每个帖子生成处理Promise
  const postProcessingPromises = tumblrPosts.map(async post => {
    if (post.type !== 'video') {
      return {...post, video_thumbnail_id: null};
    }
    
    const vimeoIdMatch = post.body.match(/vimeo\.com\/(\d+)/);
    if (!vimeoIdMatch) {
      return {...post, video_thumbnail_id: null};
    }
    const vimeoId = vimeoIdMatch[1];
    
    try {
      const response = await fetch(`https://api.vimeo.com/videos/${vimeoId}`, {
        headers: {'Authorization': 'Bearer YOUR_VIMEO_ACCESS_TOKEN'}
      });
      
      if (!response.ok) throw new Error(`请求失败:${response.status}`);
      const videoData = await response.json();
      const thumbnailId = videoData.pictures?.sizes?.[2]?.uri?.split('/').pop() || null;
      
      return {...post, video_thumbnail_id: thumbnailId};
    } catch (err) {
      console.error(`处理视频ID ${vimeoId} 出错:`, err);
      return {...post, video_thumbnail_id: null};
    }
  });
  
  // 等待所有Promise完成,得到最终数组
  return await Promise.all(postProcessingPromises);
}

// 调用示例
processVideoPosts().then(processedPosts => {
  // 处理结果
});

关键注意点

  • 所有异步操作必须用await等待完成,包括fetch请求和response.json()解析
  • Vimeo API需要有效的授权Token,否则会返回权限错误,请替换为你的合法Token
  • 提取Vimeo ID的正则表达式需要根据你帖子body的实际格式调整,确保匹配准确
  • 加入错误捕获逻辑,避免单个请求失败导致整个处理流程中断

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 06:33:29