我有这种方法:
updateCustomers = (input) => {
//let urls = input
let urls=[{
name: "localhost:8081",
url: "http://localhost:8081"
},
{
name: "localhost:8082",
url: "http://localhost:8081"
},
{
name: "localhost:8083",
url: "http://localhost:8081"
}]
alert( urls.length)
urls.map((url, index) => {
let paramsNode = {
customer: this.props.match.params.customer,
environment: this.props.match.params.environment,
action: 'check',
node: url.name
}
console.log("url: "+url.name)
console.log("***********************")
this.gatewayService.manageServices(paramsNode, (callback) => this.checkServiceNode(callback, index, url))
})
}
请忽略paramsNode变量,我要显示的是我想对列表的每个成员进行api调用。
这是我的api调用:
manageServices=(params,callback)=>{
let url = this.baseUrl;
if(params.customer == null || params.environment == null) {
throw "The customer or environment parameter cant be null.";
}
url += "/" + params.customer + "/" + params.environment + "/"+params.node +"/configurations/manageServices/" + params.action;
url = encodeURI(url);
RestUtils.fetchJsonFromApi(url,callback);
}
这是RestUtils方法:
static fetchJsonFromApi(url, callback) {
return fetch(url)
.then(response => response.json())
.then(json => {
console.log("fetchJsonFromApi " + JSON.stringify(json))
// making callback optional
if (callback && typeof callback === "function") {
callback(json);
}
return json;
})
.catch(error => {
console.log(error)
});
}
调用完成后,它将执行以下方法:
checkServiceNode = (result, index,node) => {
console.log("--------------------------")
console.log("HERE"+node.name)
console.log("##########################")
}
我想做的是按以下顺序打印此值:
url: localhost:8081
***********************
--------------------------
HERE localhost:8081
##########################
url: localhost:8082
***********************
--------------------------
HERE localhost:8082
##########################
url: localhost:8083
***********************
--------------------------
HERE localhost:8083
##########################
但是我得到的是(顺序总是随机的):
url: localhost:8081
***********************
url: localhost:8082
***********************
url: localhost:8083
***********************
--------------------------
HERE localhost:8082
##########################
--------------------------
HERE localhost:8083
##########################
--------------------------
HERE localhost:8081
##########################
如何确保打印顺序?
答案 0 :(得分:1)
Array.prototype.map
不会在完成下一个API调用之前等待当前的API调用完成。因此,API调用完成的顺序取决于网络延迟和其他因素,这些因素使得顺序大多不确定。
如果要按顺序(一个接一个地)进行API调用,则可以编写一个函数,该函数将在上一个promise(api调用)解决后处理每个下一个url,例如,可以如下实现: / p>
const asyncSeries = (fn, items) => items.reduce((acc, item) => {
return acc.then(collection =>
fn(item).then(result =>
collection.concat(result)
)
)
}, Promise.resolve([]));
要使其正常工作,您需要使发送api调用(manageServices
)的函数返回承诺:
return RestUtils.fetchJsonFromApi(url,callback);
然后,您可以按以下顺序进行API调用:
asyncSeries((url, index) => {
let paramsNode = {
customer: this.props.match.params.customer,
environment: this.props.match.params.environment,
action: 'check',
node: url.name
}
console.log("url: "+url.name)
console.log("***********************")
return this.gatewayService.manageServices(paramsNode, (callback) => this.checkServiceNode(callback, index, url))
}, urls)
答案 1 :(得分:0)
您正在使用fetch
进行到端点的调用,并且fetch
可以使用诺言。 Promise
对象上有一个名为all
的方法,该方法将一个promise列表作为参数,并在它们全部单独解析时进行解析。在then
回调中,它作为第一个参数传递,其中包含每个承诺的已解决结果的列表。
Here is the documentation for the Promise.all
method
这是如何使用它的基本示例。为了简化这种情况,我用一个模拟重写了fetch
函数,该函数在随机的时间后解析。这样,每次运行时,每个承诺都会以不同的顺序解决。但是,result
调用中的Promise.all
返回的顺序与调用时的顺序相同。
function fetch(url) {
var randomTimeout = Math.round(Math.random() * 1000, 0)
return new Promise(function(resolve) {
setTimeout(function() { resolve({url:url, timeout: randomTimeout}) }, randomTimeout);
});
}
function callMultipleAPI(urlList) {
return Promise.all(urlList.map(function (url) { return fetch(url); }));
}
var urlList = ['http://localhost:8081/', 'http://localhost:8082/', 'http://localhost:8083'];
callMultipleAPI(urlList)
.then(function(result) { console.log(JSON.stringify(result, null, 2)); });
/*
Result:
[
{
"url": "http://localhost:8081/",
"timeout": 869
},
{
"url": "http://localhost:8082/",
"timeout": 508
},
{
"url": "http://localhost:8083",
"timeout": 269
}
]
*/
希望有帮助。
答案 2 :(得分:0)
已在2019年使用异步 / 等待:
let urls=[{
name: "localhost:8081",
url: "http://localhost:8081"
},
{
name: "localhost:8082",
url: "http://localhost:8081"
}]
const promises = []
// make asynchronous api call for each endpoint
// and save promise of call in array
for(const url of urls) {
promises.push(fetch(url.url))
console.log(`endpoint ${url.name} called`)
}
const results = []
// asyncronously await all of the calls and push result in same order
for(const promise of promises) {
results.push(await promise))
// or use result right now
}
// use array of results as you need
for(const result of results) {
console.log(result)
}
// or with positioned access
results.map( (result, pos) => {
console.log(`endpoint ${urls[pos]} result: `, result)
})