इस समस्या को "कॉलबैक हेल" कहा जाता है . और भी कई तरीके हैं जैसे Promise का उपयोग करना और Async पुस्तकालय आपको मिलेंगे।
मैं मूल निवासी के बारे में अधिक उत्साहित हूं async
ES7
लाएगा, जिसे आप वास्तव में आज ट्रांसपिलर लाइब्रेरी Babel
के साथ उपयोग करना शुरू कर सकते हैं ।
लेकिन अब तक मैंने जो सबसे सरल तरीका खोजा है, वह निम्नलिखित है:आप लंबे कॉलबैक फ़ंक्शन निकालते हैं और उन्हें बाहर परिभाषित करते हैं।
router.route('/report') // the REST api address
.post(calling_a_POST)
function calling_a_POST(req, res) {
...
var data = "";
https.get(url, function callback(response) {
...
response.on("end", response_on_end_callback); // --> take out
response.on("error", console.error);
});
}
function response_on_end_callback() { // <-- define here
...
for (var i = 0; i < length; i++) {
var report = new Report(array.pop());
...
Report.find({ id: report['id'] })
.count(Report_find_count_callback); // --> take out
};
res.json({
message: 'Grabbed Report'
});
}
function Report_find_count_callback(err, count) { // <-- define here
...
if (count == 0) {
report.save(function(err) { // !! report is undefined here
console.log('saved');
if (err)
res.send(err); // !! res is undefined here
});
}
}
एक चेतावनी यह है कि आप उन सभी चरों तक पहुँचने में सक्षम नहीं होंगे जो कॉलबैक हुआ करते थे, क्योंकि आपने उन्हें दायरे से बाहर कर दिया है।
इसे आवश्यक चरों को पारित करने के लिए "निर्भरता इंजेक्शन" आवरण के साथ हल किया जा सकता है।
router.route('/report') // the REST api address
.post(calling_a_POST)
function calling_a_POST(req, res) {
...
var data = "";
https.get(url, function callback(response) {
...
response.on("end", function(err, data){ // take these arguments
response_on_end(err, data, res); // plus the needed variables
});
response.on("error", console.error);
});
}
function response_on_end(err, data, res) { // and pass them to function defined outside
...
for (var i = 0; i < length; i++) {
var report = new Report(array.pop());
...
Report.find({ id: report['id'] })
.count(function(err, count){
Report_find_count(err, count, report, res); // same here
});
};
res.json({ // res is now available
message: 'Grabbed Report'
});
}
function Report_find_count(err, count, report, res) { // same here
...
if (count == 0) {
report.save(function(err) { // report is now available
console.log('saved');
if (err)
res.send(err); // res is now available
});
}
}
मुझे एहसास हुआ कि मैंने यहां एक त्रुटि की है:
function calling_a_POST(req, res) {
...
var data = "";
https.get(url, function callback(response) {
...
//sponse.on("end", function(err, data){
response.on("end", function(err){ // data shouldn't be here
response_on_end(err, data, res);
});
response.on("error", console.error);
});
}
एक और समस्या जो मैं देख सकता था, जो वास्तव में यहां उत्पन्न नहीं हो सकती है लेकिन फिर भी किसी भी तरह से बात करना बेहतर होगा। data
चर, चूंकि यह एक स्ट्रिंग है जो एक वस्तु के विपरीत एक आदिम प्रकार है, यह "मूल्य द्वारा पारित" है। अधिक जानकारी
किसी ऑब्जेक्ट में वेरिएबल को लपेटना और ऑब्जेक्ट को पास करना बेहतर है, क्योंकि जावास्क्रिप्ट में ऑब्जेक्ट हमेशा "संदर्भ द्वारा पारित" होते हैं।
function calling_a_POST(req, res) {
...
// var data = ""; //
var data_wrapper = {};
data_wrapper.data = {}; // wrap it in an object
https.get(url, function callback(response) {
...
response.on("data", function(chunk){
data_wrapper.data += chunk.toString() + ""; // use the dot notation to reference
});
response.on("end", function(err){
response_on_end(err, data_wrapper, res); // and pass that object
});
response.on("error", console.error);
});
}
function response_on_end_callback(err, data_wrapper, res) {
var data = data_wrapper.data; // later redefine the variable
...
for (var i = 0; i < length; i++) {
var report = new Report(array.pop());
...