如何在循环/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
相关产品推荐
相关产品推荐

