我是nodejs的新手所以请原谅我是否想念显而易见的事情。 我目前正在努力处理代码的异步操作。它是这样的。我运行快速框架来调用调用外部REST服务器的特定URL来获取有关对象的一些信息。我没有基本操作的问题,我处理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页面,之后我会获得getVolumeDetails()的控制台消息,因为javascript的异步特性。 我读过很多关于使用request-promise,async.each,async wait,callbacks的文章,并且仍然很难理解如何使它工作。我不介意等待几秒钟让循环完成获取所有卷的详细信息,用我想要在HTML页面上显示的项目数组填充我的element_list。 你可以帮我指导一下构造使用的方法和方法吗?
感谢。
答案 0 :(得分:0)
这是我的修改:
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)
.then(function (body) {
output_json = JSON.parse(body);
console.log('Raw body of listVolumes(): \n' , body);
if (Object.keys(output_json).length > 0){
async.each(output_json.list, function (volume_id, callback){
options.url = MY_ENV.MY_URL + '/v2/volumes/' + volume_id;
request(options)
.then(function (body) {
var volume = JSON.parse(body);
console.log('got callback: ' , volume.id, volume.name , volume.size, volume.state);
element_list.push({ id: volume.id, name: volume.name, size: volume.size, state: volume.state });
callback(null);
})
.catch (function (error) {
console.log('Got error while reading volume: ' + volume_id , error.message);
});
},
function (err){
if (err) {
console.log('Error occured: ', err);
} else {
console.log('All done...Element list length: ', element_list.length); // this never runs... why???
}
res.render('listVolumes', {element, element_list, output_json });
});
} else console.log('No volumes found.');
})
.catch (function (error) {
console.log('Got error while listing ' + element , error);
});
}
因此它永远不会运行函数(错误)中的代码,我将注释// this never runs... why???