Node.js循环调用Jira API如何收集所有异步响应并返回结果对象
核心问题说明
你遇到的问题是异步回调执行时机晚于函数同步返回时机,请求还没响应时就已经把空对象返回,自然拿不到结果。可以通过Promise + async/await的方案解决,具体实现如下:
方案1:使用支持Promise的HTTP库(推荐,比如axios)
首先安装依赖:
npm install axios
改造后的函数代码:
const axios = require('axios'); // 函数标记为async,返回Promise const getallJira = async (namespace, services) => { // 生成所有请求的Promise数组 const requestPromises = services.map(async _serviceName => { const options = { method: 'POST', url: 'https://jira/jira/rest/api/2/search', headers: { 'Content-Type': 'application/json', Authorization: base64Auth, Accept: 'application/json', }, data: { jql: `NAMESPACE = ${namespace} AND labels = 'kind/promotion' AND (SERVICE_NAME = '${_serviceName}' OR 'Service Name/Package Name' = '${_serviceName}')`, maxResults: 1000000, startAt: 0, fields, } }; try { const response = await axios(options); // 把服务名和对应的响应成对返回,用于后续组装对象 return [_serviceName, response.data]; } catch (error) { // 单个请求失败的处理,可按需修改,避免单个请求失败中断所有请求 console.error(`查询${_serviceName}的Jira数据失败:`, error); return [_serviceName, null]; } }); // 等待所有请求完成 const allResults = await Promise.all(requestPromises); // 把结果数组转换成你需要的对象结构 return Object.fromEntries(allResults); };
调用方式
因为async函数返回的是Promise,你需要用await或者.then拿结果:
// 方式1:在async函数内用await调用 const jiraData = await getallJira('你的namespace', ['service1', 'service2']); console.log(jiraData); // 方式2:用.then链式调用 getallJira('你的namespace', ['service1', 'service2']).then(jiraData => { console.log(jiraData); });
方案2:如果必须使用原生request库
可以手动把request回调包装成Promise:
const req = require('request'); const getallJira = async (namespace, services) => { // 包装request为Promise const requestPromise = (options) => new Promise((resolve, reject) => { req(options, (error, response) => { if (error) return reject(error); resolve(JSON.parse(response.body)); }); }); const requestPromises = services.map(async _serviceName => { const options = { method: 'POST', url: 'https://jira/jira/rest/api/2/search', headers: { 'Content-Type': 'application/json', Authorization: base64Auth, Accept: 'application/json', }, body: JSON.stringify({ jql: `NAMESPACE = ${namespace} AND labels = 'kind/promotion' AND (SERVICE_NAME = '${_serviceName}' OR 'Service Name/Package Name' = '${_serviceName}')`, maxResults: 1000000, startAt: 0, fields, }), }; try { const data = await requestPromise(options); return [_serviceName, data]; } catch (error) { console.error(`查询${_serviceName}的Jira数据失败:`, error); return [_serviceName, null]; } }); const allResults = await Promise.all(requestPromises); return Object.fromEntries(allResults); };
调用方式和方案1完全一致。
内容的提问来源于stack exchange,提问作者Viswajith Kalavapudi
相关产品推荐
相关产品推荐

