【发布时间】:2018-04-11 22:57:17
【问题描述】:
我是 nodejs 的新手,所以如果我错过了明显的内容,请原谅。 我目前正在为我的代码的异步操作而苦苦挣扎。它是这样的。我运行 express 框架来调用特定的 URL,该 URL 调用外部 REST 服务器以获取有关对象的一些信息。我处理 REST 响应、解析 JSON 并将信息传递给 EJS 视图引擎以呈现 HTML 页面的基本操作没有问题。 但是,我在一个特定的过程中遇到问题,在我得到 REST 响应(卷列表)之后,我想运行另一个 REST 调用以获取有关每个卷的更多详细信息(循环中)。检索完成后,我想调用 EJS 来呈现包含卷列表及其详细信息的页面。 这是我的代码:
function listVolumes(req, res) {
var element = 'volume';
var element_list= [];
var output_json = [];
var options = { method: 'GET',
url: MY_ENV.MY_URL + '/v2/volumes',
headers:
{
'Cache-Control': 'no-cache',
'X-Auth-Token': MY_ENV.MY_TOKEN,
'Content-Type': 'application/json',
'Accept': 'application/json' }
}
request(options) // using request-promise
.then(function (body) {
output_json = JSON.parse(body); // parsing array of JSON objects from REST server
if (Object.keys(output_json).length > 0){
for (var i in output_json.list) { // iterating over list of JSON objects
var volume_id = output_json.list[i];
console.log(i, ': ' , JSON.stringify(volume_id, null, 3));
getVolumeDetails(volume_id, function callback(volume){ // getting volume details
element_list.push({ id: volume_id, name: volume.name, size: volume.size, state: volume.state });
});
}
res.render('listVolumes', {element, element_list, output_json }); // calling ejs view-engine to render html page
} else console.log('No volumes found.');
})
.catch (function (error) {
console.log('Got error while listing ' + element , error);
});
}
function getVolumeDetails(volume_id, callback){
var options = { method: 'GET',
url: MY_ENV.MY_URL + '/v2/volumes/' + volume_id,
headers:
{
'Cache-Control': 'no-cache',
'X-Auth-Token': MY_ENV.MY_TOKEN,
'Content-Type': 'application/json',
'Accept': 'application/json' } };
request(options)
.then(function (body) {
volume = JSON.parse(body);
console.log('got volume: ' , volume.name , volume.size, volume.state);
callback(volume);
})
.catch (function (error) {
console.log('Got error while reading volume: ' + volume_id , error.message);
});
}
app.get('/list/volumes', listVolumes);
很明显,当我调用 EJS 时,它会呈现 HTML 页面,然后由于 javascript 的异步特性,我会收到 getVolumeDetails() 的控制台消息。 我已经阅读了许多关于使用 request-promise、async.each、async wait、回调的文章,但仍然难以理解如何使其工作。我不介意等待几秒钟让循环完成获取所有卷的详细信息,用我想在 HTML 页面上显示的项目数组填充我的 element_list。 您能帮我指导使用什么构造以及如何使用吗?
谢谢。
【问题讨论】:
-
你检查过async.queue吗?你也可以试试递归。
-
我做了一些更改并且能够 async.each() 工作,但我发现它永远不会完成,即在所有迭代函数都运行后永远不会运行第三个函数。知道为什么吗?
标签: node.js