Postman / pm api sendRequest 命令:如何等到响应返回后再填充变量?
Posted
技术标签:
【中文标题】Postman / pm api sendRequest 命令:如何等到响应返回后再填充变量?【英文标题】:Postman / pm api sendRequest command: how to wait till the response is back before populating the variable? 【发布时间】:2018-05-04 11:24:55 【问题描述】:我正在尝试使用邮递员的 pm api sendRequest 创建响应 json 的字典对象。
编写了一个递归函数来获取所有响应,但问题是响应字典对象填充发生在响应返回之前。
有没有办法在接收到每个相应的响应之前等待字典填充,以便在字典对象中捕获响应?
var respDictionary = ;
getResponses (listOfUrls);
console.log("respDictionary: ");
console.log(respDictionary);
function getResponses(urlList)
if (typeof urlList === 'string')
urlList = urlList.split(' ');
_url = urlList[0];
var call =
url: _url ,
method: 'GET',
header:
"Authorization": `Bearer $token`,
"Content-Type": "application/json"
;
urlList.splice(0, 1);
pm.sendRequest(
call,
function (err, res)
if (err)
console.log(err);
else
if (urlList.length === 0)
return;
try
respDictionary[_url] = res.json();
catch (e)
console.log(err);
getResponses(urlList);
);
console.log(respDictionary);
输出是:
respDictionary:
Object:
//further, pm request responses are listed
【问题讨论】:
我更新了我的答案,在您的代码中,下一个 url 将在前一个 URL 完成后打开(串行)。我的代码会立即打开所有网址。对于大量的 url,最好限制打开连接的数量,所以我添加了一个限制。 【参考方案1】:除了其他答案之外,以下简单方法也可以很好地代替递归:
_.forEach (
urls,
function (urls)
getAPI(url,function (url,schema,err)
if (!err)
respDictionary[url]=resp.json();
console.log(schema);
else
console.log(err);
pm.environment.set('respDictionary', JSON.stringify(respDictionary));
);
);
function getAPI(url, callback)
var _url = 'BP_SERVER/' + urls;
var call =
url: _url,
method: 'GET',
header:
"Authorization": `Bearer $token`,
"Content-Type": "application/json"
;
pm.sendRequest(
call,
function (err, res)
if (!err)
callback(urls,res.json());
else
callback(urls,'',err);
);
【讨论】:
【参考方案2】:您不了解 javascript 异步处理。也许以下内容会有所帮助:
Event loop video
Promises
Event loop documentation(视频更简单)
如果您使用 Promise,您的代码将起作用:
function getResponses(urlList)
if (typeof urlList === 'string')
urlList = urlList.split(' ');
return Promise.all(
urlList.map(
function(url)
return
url: url ,
method: 'GET',
header:
//not sure where token comes from
"Authorization": `Bearer $token`,
"Content-Type": "application/json"
;
).map(
function(call)
return new Promise(
function(resolve,reject)
pm.sendRequest(
call,
function (err, res)
if (err)
reject(err);
else
resolve([call.url,res.json()]);
);
)
.then(
undefined
,function(err)
//if something goes wrong we will still return something
return [call.url,error:err];
)
)
)
.then(
function(results)
return results.reduce(
function(acc,result)
acc[result[0]] = result[1];
,
);
)
getResponses (listOfUrls)
.then(//this will always succeed, failed items have error:something
function(results)
console.log("results:",results);
);
console.log("this comes before results");
上面的代码会导致所有请求同时发生,这可能不是我们想要的行为,我写了一个throttle method,它是一些可能派上用场的库函数的一部分。您可以将油门应用于您的代码,这样它就只有最大数量的连接:
const max = 10;//maximum 10 active connections
function getResponses(urlList)
const throttled = throttle(max);
if (typeof urlList === 'string')
urlList = urlList.split(' ');
return Promise.all(
urlList.map(
function(url)
return
url: url ,
method: 'GET',
header:
//not sure where token comes from
"Authorization": `Bearer $token`,
"Content-Type": "application/json"
;
).map(
throttled(//only max amount of connections active at any time
function(call)
return new Promise(
function(resolve,reject)
pm.sendRequest(
call,
function (err, res)
if (err)
reject(err);
else
resolve([call.url,res.json()]);
);
)
.then(
undefined
,function(err)
//if something goes wrong we will still return something
return [call.url,error:err];
)
)
)
)
.then(
function(results)
return results.reduce(
function(acc,result)
acc[result[0]] = result[1];
,
);
)
getResponses (listOfUrls)
.then(//this will always succeed, failed items have error:something
function(results)
console.log("results:",results);
);
console.log("this comes before results");
【讨论】:
以上是关于Postman / pm api sendRequest 命令:如何等到响应返回后再填充变量?的主要内容,如果未能解决你的问题,请参考以下文章
温故知新,.Net Core遇见Postman(API Development),进阶分布式微服务高效调式