[英]Node.JS - How to escape multiple nested callbacks?
我目前有一個expressJS應用程序,我正在嘗試使用getStats
函數從API檢索信息。 但是,我寫的profile
路由似乎是多個嵌套的回調。 我該如何預防? 有沒有辦法讓它獲取所有統計信息,然后在檢索所有統計信息后將其分配給變量?
function getStats(access_token, time_range, x, callback) {
var stats = [];
var options = {
url: 'www.example.com',
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);
});
});
});
});
});
});
});
承諾使您能夠避免像剛剛顯示的那樣進行回調嵌套。 請參閱我的示例,以Promise形式說明您的示例:
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"));
});
});
如您所見,嵌套的回調結構被替換為更具可讀性的格式。 在此處閱讀有關諾言的更多信息。
甚至可以使用Promise.all重寫上面的內容 ,它看起來更好:
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"));
});
});
Promise將對此有所幫助,或者將您的回調移動到路由之外的自己的函數表達式中,然后在路由中調用一次將有所幫助。
回調地獄的問題在於您沒有使用Express應用程序支持它的中間件。
基本上,編寫快速應用程序的方法是依靠回調等。 但與此相反的是,這將導致您所指出的回調地獄。
承諾也會發生這種情況,如果處理不當,就會將其稱為承諾地獄。
避免這兩種模式的最佳方法是進入中間件解決方案。
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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.