这个问题被称为“回调地狱”。还有很多其他方法,例如使用Promise和Async库。
我对本机
asyncES7所带来的一切感到更加兴奋,您实际上可以立即使用Transpiler库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 }); }}当我执行response_on_end函数时,
undefined:1 unexpected tokenu出现错误。我非常确定这与以下行有关:var jsonData = JSON.parse(data)
我response_on_end的如下:var jsonData = JSON.parse(data); // problem here
我意识到我在这里犯了一个错误:
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变量,因为它是一个字符串,它是不同于对象的原语类型,它是“按值传递”。
更多信息
最好将变量包装在一个对象中并传递该对象,因为javascript中的对象总是“通过引用传递”。
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()); ...


