JS生成器与Promise异步问题:调用Twitch API无结果返回
解决Twitch API批量请求中的Promise与生成器异步返回问题
看起来你在批量调用Twitch API时踩了异步处理的坑——这种情况太常见了,尤其是批量Promise和生成器结合的时候很容易出错。我帮你拆解问题并重构代码,顺便优化下变量命名(完全理解赶工的时候命名随便写的痛苦😂)。
核心问题分析
你现在的代码大概率是这几个原因导致不返回结果:
- 没有用
Promise.all等待所有批量请求完成,函数直接提前返回了空数组 - 缺少错误捕获,某个请求失败后整个Promise链静默挂掉,你根本看不到报错
- 如果涉及生成器,可能是没有正确处理异步迭代,导致生成器的批次没被等待
基础版修复:正确处理批量Promise
先给你一个最基础的修复版本,解决Promise不返回结果的问题:
exports.batchPromiseWrapper = async function(arr) { // 改用语义化变量名,避免拼写错误(你之前的promiseBatachArray拼错了batch) const processedMarkers = []; // 生成所有API请求的Promise数组 const requestPromises = arr.map(vodItem => { const markerApiUrl = `https://api.twitch.tv/kraken/videos/${vodItem.id}/markers`; const requestConfig = { params: { api_version: 5 }, headers: { "Client-ID": "xxxxxxxxxxxxxxx" } }; return axios.get(markerApiUrl, requestConfig) .then(response => { // 把需要的数据存入数组,这里假设你要的是返回的markers数据 const markers = response.data; processedMarkers.push(markers); return markers; }) .catch(error => { // 绝对不能忽略错误!打印出来才能排查问题 console.error(`获取VOD ${vodItem.id}标记失败:`, error.message); // 返回null避免单个失败导致整个Promise.all挂掉 return null; }); }); // 关键!等待所有请求完成,不然函数会直接返回空数组 await Promise.all(requestPromises); // 返回最终处理后的数组 return processedMarkers; };
进阶版:生成器分批处理(避免API限流)
如果是用生成器做分批请求(防止Twitch API触发速率限制),那得配合异步迭代来处理,不然生成器的批次不会等待请求完成:
// 生成器函数:把数组切成指定大小的批次 function* vodBatchGenerator(vodList, batchSize) { for (let i = 0; i < vodList.length; i += batchSize) { yield vodList.slice(i, i + batchSize); } } exports.batchPromiseWrapper = async function(vodList, batchSize = 10) { const allProcessedMarkers = []; const batchGenerator = vodBatchGenerator(vodList, batchSize); // 用for await...of遍历生成器,确保每一批请求完成后再处理下一批 for await (const currentBatch of batchGenerator) { const batchPromises = currentBatch.map(vodItem => { const markerApiUrl = `https://api.twitch.tv/kraken/videos/${vodItem.id}/markers`; const requestConfig = { params: { api_version: 5 }, headers: { "Client-ID": "xxxxxxxxxxxxxxx" } }; return axios.get(markerApiUrl, requestConfig) .then(res => res.data) .catch(err => { console.error(`VOD ${vodItem.id}请求失败:`, err.message); return null; }); }); // 等待当前批次所有请求完成,收集结果并过滤掉失败的 const batchResults = await Promise.all(batchPromises); allProcessedMarkers.push(...batchResults.filter(item => item !== null)); } return allProcessedMarkers; };
排查异步问题的几个关键点
- 必须用
Promise.all等待批量Promise:这是最容易忘的点,没有它的话,函数会在所有请求开始前就返回空数组 - 不要忽略错误捕获:异步错误会静默失败,加
catch才能知道哪出问题 - 变量作用域要注意:别用
var,改用const/let,避免循环里的变量泄漏 - 生成器配合异步迭代:如果用生成器做分批,一定要用
for await...of或者手动迭代并等待每个批次的Promise完成
内容的提问来源于stack exchange,提问作者David Trinh
相关产品推荐
相关产品推荐

