nodejs中的变量作用域误解

Variable Scope in nodejs misunderstanding

本文关键字:作用域 误解 变量 nodejs      更新时间:2023-09-26

我很难理解为什么从另一个函数返回一个数组只局限于一个代码块。即:

exports.join = function(req, res){
  User.findById(req.user._id, function(err, user) {
     var dupe = []; //placeholder array
     var arr = user.forms_container.joinList;
     var title = user.forms_container.title;
     arr.forEach(function (rep) {
      //console.log(rep);
      Report.findById(rep).deepPopulate('subreport.subreport.subreport.subreport.subreport.subreport').execAsync()
      .then(function(doc) {
        //console.log(doc);
        dupe.push(doc);
        treeCycle(doc, dupe);
        console.log(dupe);
      }).catch(function(err) {
        throw err;
      });
      tracker = tracker + 1;
      if(tracker == arr.length) {
        console.log(dupe); //returns [];
        var counter = 0;
        var masterbody;
        for(var x = 0; x < dupe.length; x++) {
           masterbody = masterbody + dupe[x].body;
           counter = counter + 1;
        }
        if(counter==dupe.length) {
          newDoc.body = masterbody;
          //newDoc.save();
          res.json(newDoc);
        }
      }
     });
  });
};

一次,我调用treeCycle,它将迭代该函数(递归函数)并开始填充数组"dupe",如果我在控制台中记录它,它显示它已经完成,这是控制台c/p'd:

[ { _id: 55c35cd942dd12ec19b30f2e,
    owner: 55a80b8404dc0dc8187395d8,
    title: 'Chrome1',
    date: 'Thu Aug 06 2015 09:10:49 GMT-0400 (Eastern Daylight Time)',
    body: '123213',
    __v: 0,
    isCompleted: false,
    subreport: [],
    authors: [ 'Karan Kotwal' ],
    author: [ 55a80b8404dc0dc8187395d8 ] } ]
[ { _id: 55c35cd942dd12ec19b30f2e,
    owner: 55a80b8404dc0dc8187395d8,
    title: 'Chrome1',
    date: 'Thu Aug 06 2015 09:10:49 GMT-0400 (Eastern Daylight Time)',
    body: '123213',
    __v: 0,
    isCompleted: false,
    subreport: [],
    authors: [ 'Karan Kotwal' ],
    author: [ 55a80b8404dc0dc8187395d8 ] },
  { _id: 55c8d774e904bc141681e115,
    body: 'dddd',
    owner: 55a80b8404dc0dc8187395d8,
    date: 'Mon Aug 10 2015 12:55:16 GMT-0400 (Eastern Daylight Time)',
    title: 'herdrute',
    __v: 1,
    isCompleted: false,
    subreport: [],
    authors: [ 'Karan Kotwal' ],
    author: [ 55a80b8404dc0dc8187395d8 ] } ]
[ { _id: 55c35cd942dd12ec19b30f2e,
    owner: 55a80b8404dc0dc8187395d8,
    title: 'Chrome1',
    date: 'Thu Aug 06 2015 09:10:49 GMT-0400 (Eastern Daylight Time)',
    body: '123213',
    __v: 0,
    isCompleted: false,
    subreport: [],
    authors: [ 'Karan Kotwal' ],
    author: [ 55a80b8404dc0dc8187395d8 ] },
  { _id: 55c8d774e904bc141681e115,
    body: 'dddd',
    owner: 55a80b8404dc0dc8187395d8,
    date: 'Mon Aug 10 2015 12:55:16 GMT-0400 (Eastern Daylight Time)',
    title: 'herdrute',
    __v: 1,
    isCompleted: false,
    subreport: [],
    authors: [ 'Karan Kotwal' ],
    author: [ 55a80b8404dc0dc8187395d8 ] },
  { _id: 55bf7465c60c959015dee0ed,
    owner: 55a80b8404dc0dc8187395d8,
    title: 'ffefeeffefeeffefefe',
    date: 'Mon Aug 03 2015 10:02:13 GMT-0400 (Eastern Daylight Time)',
    body: 'efefefefef',
    __v: 0,
    isCompleted: false,
    subreport: [],
    authors: [ 'Karan Kotwal' ],
    author: [ 55a80b8404dc0dc8187395d8 ] } ]
[ { _id: 55c35cd942dd12ec19b30f2e,
    owner: 55a80b8404dc0dc8187395d8,
    title: 'Chrome1',
    date: 'Thu Aug 06 2015 09:10:49 GMT-0400 (Eastern Daylight Time)',
    body: '123213',
    __v: 0,
    isCompleted: false,
    subreport: [],
    authors: [ 'Karan Kotwal' ],
    author: [ 55a80b8404dc0dc8187395d8 ] },
  { _id: 55c8d774e904bc141681e115,
    body: 'dddd',
    owner: 55a80b8404dc0dc8187395d8,
    date: 'Mon Aug 10 2015 12:55:16 GMT-0400 (Eastern Daylight Time)',
    title: 'herdrute',
    __v: 1,
    isCompleted: false,
    subreport: [],
    authors: [ 'Karan Kotwal' ],
    author: [ 55a80b8404dc0dc8187395d8 ] },
  { _id: 55bf7465c60c959015dee0ed,
    owner: 55a80b8404dc0dc8187395d8,
    title: 'ffefeeffefeeffefefe',
    date: 'Mon Aug 03 2015 10:02:13 GMT-0400 (Eastern Daylight Time)',
    body: 'efefefefef',
    __v: 0,
    isCompleted: false,
    subreport: [],
    authors: [ 'Karan Kotwal' ],
    author: [ 55a80b8404dc0dc8187395d8 ] },
  { _id: 55c361705d00464419a1d40c,
    owner: 55a80b8404dc0dc8187395d8,
    title: 'IE11',
    date: 'Thu Aug 06 2015 09:30:24 GMT-0400 (Eastern Daylight Time)',
    body: 'PEWPEWPEWPW',
    __v: 1,
    isCompleted: false,
    subreport:
     [ { _id: 55ca4d5456f8cdb416d36092,
         body: 'testest',
         owner: 55a80b8404dc0dc8187395d8,
         date: 'Tue Aug 11 2015 15:30:28 GMT-0400 (Eastern Daylight Time)',
         title: 'Sub1',
         __v: 2,
         parentReport: 55c361705d00464419a1d40c,
         isCompleted: false,
         subreport: [Object],
         authors: [Object],
         author: [Object] } ],
    authors: [ 'Karan Kotwal' ],
    author: [ 55a80b8404dc0dc8187395d8 ] },
  { _id: 55ca4d5456f8cdb416d36092,
    body: 'testest',
    owner: 55a80b8404dc0dc8187395d8,
    date: 'Tue Aug 11 2015 15:30:28 GMT-0400 (Eastern Daylight Time)',
    title: 'Sub1',
    __v: 2,
    parentReport: 55c361705d00464419a1d40c,
    isCompleted: false,
    subreport:
     [ { _id: 55ca53728ecc9400150610b6,
         body: 'sadsadasdasdasdadasdsadasdasEnter subreport here',
         owner: 55a80b8404dc0dc8187395d8,
         date: 'Tue Aug 11 2015 15:56:34 GMT-0400 (Eastern Daylight Time)',
         title: 'Sub1''s sub1',
         __v: 1,
         parentReport: 55ca4d5456f8cdb416d36092,
         isCompleted: false,
         subreport: [],
         authors: [Object],
         author: [Object] } ],
    authors: [ 'Jeff The man' ],
    author: [ 55ad14bac2419660021d80b0 ] },
  { _id: 55ca53728ecc9400150610b6,
    body: 'sadsadasdasdasdadasdsadasdasEnter subreport here',
    owner: 55a80b8404dc0dc8187395d8,
    date: 'Tue Aug 11 2015 15:56:34 GMT-0400 (Eastern Daylight Time)',
    title: 'Sub1''s sub1',
    __v: 1,
    parentReport: 55ca4d5456f8cdb416d36092,
    isCompleted: false,
    subreport: [],
    authors: [ 'Empty Empty' ],
    author: [ 55bbbc20877f48a01bf0c8d9 ] } ]

但是这样做,调用数组dupe的最终版本的控制台将返回空。我在块if(tracker == array.length);中这样做,我认为它的作用域将贯穿整个函数,因为我在开始时初始化了它。

TreeCycle:

function treeCycle(doc, arr) {
  if(doc.subreport.length != 0) {
    for (var x = 0; x < doc.subreport.length; x++){
      arr.push(doc.subreport[x]);
      //console.log(arr);
      if(doc.subreport[x].subreport.length != 0) {
        treeCycle(doc.subreport[x], arr);
      }
    }
  }
  else {
    return arr;
  }
};

这似乎是一个异步问题,您的if(tracker == arr.length) {部分在树周期之前运行。当你的异步任务完成后,你需要调用你的if(tracker == arr.length) {部分。

的例子:

exports.join = function(req, res) {
    User.findById(req.user._id, function(err, user) {
        var dupe = []; //placeholder array
        var arr = user.forms_container.joinList;
        var title = user.forms_container.title;
        arr.forEach(function(rep) {
            //console.log(rep);
            Report.findById(rep).deepPopulate('subreport.subreport.subreport.subreport.subreport.subreport').execAsync()
                .then(function(doc) {
                    //console.log(doc);
                    dupe.push(doc);
                    treeCycle(doc, dupe);
                    console.log(dupe);
                    tracker = tracker + 1;
                    if (tracker == arr.length) {
                        console.log(dupe); //returns [];
                        var counter = 0;
                        var masterbody;
                        for (var x = 0; x < dupe.length; x++) {
                            masterbody = masterbody + dupe[x].body;
                            counter = counter + 1;
                        }
                        if (counter == dupe.length) {
                            newDoc.body = masterbody;
                            //newDoc.save();
                            res.json(newDoc);
                        }
                    }
                }).catch(function(err) {
                    throw err;
                });
        });
    });
};

这很可能是你如何使用承诺的问题。我建议你仔细阅读它们,看看它们是如何工作的,以及你应该如何重构你的代码来更好地使用它们。

如果您将if (tracker...块移动到.then(回调(或另一个.then),它可能会工作。