我正在使用Express开发Node应用程序。我将几个http调用链接到数据api,每个调用都依赖于前面req的响应。
除了最后一个电话,一切都正常。最后一次调用需要发生多次,然后才能呈现页面。
搜索已经找到了关于如何链接的优秀示例,但每次都不使用不同的参数调用同一个API(或HTTPGET、数据端点等)。
我正在尝试做这样的事情:使用生成器多次调用API,并且只有在所有请求都完成时才解析?
var getJSON = (options, fn) => {
.....
}
router.route("/")
.get((req, res) => {
var idArray = [];
var results = [];
getJSON({
.... send params here, (result) => {
//add response to results array
results.push(result);
//create var for data nodes containing needed id params for next call
let group = result.groupsList;
//get id key from each group, save to idArray
for(i=0;i<groups.length;i++){
idArray.push(groups[I].groupId);
}
//use id keys for params of next api call
dataCallback(idArray);
});
function dataCallback(myArray){
// number of ID's in myArray determine how many times this API call must be made
myArray.forEach(element => {
getJSON({
.... send params here, (result) => {
results.push(result);
});
// put render in callback so it will render when resolved
}, myRender());
};
function myRender() {
res.render("index", { data: results, section: 'home'});
}
})
我从上面的代码中学到了这个问题。
- 您可以调用express路由之外的函数,但不能在路由内调用它们
- 不能链接多个依赖数据的调用,而不是在路由中
route.get或route.post中的任何内容都应该是关于数据、路径、渲染等的。
这意味着要么使用异步库(当我试图从多个数据源构建页面时,发现它毫无用处,数据依赖于以前的响应),要么使用一个额外的js文件(从网页)来获取,处理和建模您的数据,如下所示:使用生成器多次调用API,只有在所有请求完成后才进行解析您还可以将其放在路由之前的应用程序或索引文件中。
(起初,我不清楚代码会去哪里。我试着把它放在我的router.post里。尽管文档上写着"方法",但我并没有意识到路由就是方法。我以前只做过非常基本的路由,也从来没有看过引擎盖下面。)
我最后选择了第三种选择。我在屏幕上分解了各种API调用,这样只有当用户点击需要更多数据的东西时才会调用它们,比如手风琴或选项卡开关。
我使用网页中的XMLHttpRequest()来调用我自己的前端节点服务器,然后它调用第三方API,然后前端节点服务器使用API提供的数据响应我的pug文件。我得到了html返回我的屏幕附加。
页面中:
callFEroutetoapi(_postdata, _route, function (_newdata){
putData(_newdata);
});
function putData(tData){
var _html = tData;
var _target = document.getElementById('c-playersTab');
applyHTML(_target, _html);
}
function callFEroutetoapi(data, path, fn){
//url is express route
var url = path;
var xhr = new XMLHttpRequest();
console.log('data coming into xhr request: ', data);
//xhr methods must be in this strange order or they don't run
xhr.onload = function(oEvent) {
if(xhr.readyState === xhr.DONE) {
//if success then send to callback function
if(xhr.status === 200) {
fn(xhr.response);
// ]console.log('server responded: ', xhr.response);
}
else {
console.log("Something Died");
console.log('xhr status: ', xhr.status);
}
}
}
xhr.onerror = function (){console.log('There was an error.', xhr.status);}
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.send(JSON.stringify(data));
}
它增加了一个额外的层,但对于显示最新的、经常变化的数据是必要的。它也是可重复使用的,更适合多屏幕的网络应用程序。如果有更少的视图(完全不同的屏幕和相互依赖的数据集),上面提到的更集中的model.js文件会更好地工作。