admin管理员组文章数量:1424893
I've currently got a expressJS app and I'm trying to retrieve information from an API using the getStats
function. However, the profile
route I've written seems to be multiple nested callbacks. How would I prevent this? Is there a way to make it get all of the stats, then assign them to variables after they all of the stats are retrieved?
function getStats(access_token, time_range, x, callback) {
var stats = [];
var options = {
url: 'www.example',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
json: true
}
request(options, function(error, response, body) {
if (!error && response.statusCode == 200) {
for (i = 0; i < body.items.length; i++) {
stats.push(body.items[i].name);
}
return callback(stats);
}
})
}
app.get('/profile', function(req, res) {
var access_token = 1234;
getStats(access_token, 's', 'x', function(a){
console.log(a);
getStats(access_token, 's', 'y', function(b){
console.log(b);
getStats(access_token, 'm', 'x', function(c){
console.log(c);
getStats(access_token, 'm', 'y', function(d){
console.log(d);
getStats(access_token, 'l', 'x', function(e){
console.log(e);
getStats(access_token, 'l', 'y', function(f){
console.log(f);
res.send(a + "\n" + b + "\n" + c + "\n" + d + "\n" + e + "\n" + f);
});
});
});
});
});
});
});
I've currently got a expressJS app and I'm trying to retrieve information from an API using the getStats
function. However, the profile
route I've written seems to be multiple nested callbacks. How would I prevent this? Is there a way to make it get all of the stats, then assign them to variables after they all of the stats are retrieved?
function getStats(access_token, time_range, x, callback) {
var stats = [];
var options = {
url: 'www.example.',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
json: true
}
request(options, function(error, response, body) {
if (!error && response.statusCode == 200) {
for (i = 0; i < body.items.length; i++) {
stats.push(body.items[i].name);
}
return callback(stats);
}
})
}
app.get('/profile', function(req, res) {
var access_token = 1234;
getStats(access_token, 's', 'x', function(a){
console.log(a);
getStats(access_token, 's', 'y', function(b){
console.log(b);
getStats(access_token, 'm', 'x', function(c){
console.log(c);
getStats(access_token, 'm', 'y', function(d){
console.log(d);
getStats(access_token, 'l', 'x', function(e){
console.log(e);
getStats(access_token, 'l', 'y', function(f){
console.log(f);
res.send(a + "\n" + b + "\n" + c + "\n" + d + "\n" + e + "\n" + f);
});
});
});
});
});
});
});
Share
Improve this question
edited Sep 16, 2018 at 10:58
kockburn
17.7k10 gold badges90 silver badges143 bronze badges
asked Sep 16, 2018 at 10:24
newangnewang
1992 gold badges2 silver badges8 bronze badges
1
- 4 I would suggest that you look into Promises – SeinopSys Commented Sep 16, 2018 at 10:26
3 Answers
Reset to default 7Promises allow you to avoid the type of callback nesting like you've just shown. See my example which illustrates your example in Promise form:
function getStats(access_token, time_range, x, prevResult) {
return new Promise((resolve, reject) => {
if (prevResult) {
resolve([...prevResult, "test", "test", "test"]);
}
return resolve(["test", "test", "test"]);
});
}
app.get('/profile', (req, res) => {
var access_token = 1234;
getStats(access_token, 's', 'x')
.then((a) => {
console.log(a);
return getStats(access_token, 's', 'y', a);
})
.then((b) => {
console.log(b);
return getStats(access_token, 'm', 'x', b);
})
.then((c) => {
console.log(c);
return getStats(access_token, 'm', 'y', c);
})
.then((d) => {
console.log(d);
return getStats(access_token, 'l', 'x', d);
})
.then((e) => {
console.log(e);
return getStats(access_token, 'l', 'y', e);
})
.then((f) => {
console.log(f);
res.send(f.join("\n"));
});
});
As you can see the nested callback structure and replace with a much more readable format. Read more about promises here.
The above could even be rewritten using Promise.all, which looks even nicer:
function getStats(access_token, time_range, x) {
return new Promise((resolve, reject) => {
return resolve(["test", "test", "test"]);
});
}
app.get('/profile', (req, res) => {
var access_token = 1234;
Promise.all([
getStats(access_token, 's', 'x'),
getStats(access_token, 's', 'y'),
getStats(access_token, 'm', 'x'),
getStats(access_token, 'm', 'y'),
getStats(access_token, 'l', 'x'),
getStats(access_token, 'l', 'y')
]).then((values) => {
console.log(values);
res.send(values.join("\n"));
});
});
Promises will help with that, or moving your callbacks into their own function expressions outside of the route, and then calling it in the route once will help.
The problem with that callback hell is that you are not using middlewares where the express app is supporting it.
Basically a way to write an express app is relying in the callbacks and so on. But the counterpart is that this will lead to as what you pointed out the callback hell.
This happens also with promises as well and it's called the promise hell when not properly handled.
The best way to avoid this two patterns are moving into the middlewares solutions.
function getAccesstoken(req, res, next) {
if (!req.something) {
return next('Error, something was not specified');
}
req.someRequestVariable = 'set_something';
next();
}
function processRequest(req, res, next) {
console.log(req.someRequestVariable);
res.send(200);
}
app.use(function genericHandlerForEveryCall() {
console.log('This is being called in every request');
})
app.get('/profile', getAccesstoken, processRequest);
本文标签: javascriptNodeJSHow to escape multiple nested callbacksStack Overflow
版权声明:本文标题:javascript - Node.JS - How to escape multiple nested callbacks? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745430071a2658285.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论