简体   繁体   中英

How to return from main function via a nested function in nodejs using callbacks?

I am trying to write a validation function, that validates my request headers. It returns true if all headers are ok and false if there is something wrong. I execute this function for every (almost) request. The problem is, I don't know how to return the main function in case I use callbacks and setting any flags does not work, due to some issues with variable scope. Everything was good when I was working without callbacks, I just used underscore to query my JSONs. Now I use NeDB and bound to callbacks I cannot get the job done. I tried to use a global "res" variable but the problem is, when I assign the value of parameter "cnt" (0 if token not found, 1 if there is a token) to "res", then the value of "res" is always 1 iteration behind "cnt": ie:

request1 (valid): cnt = 1; res = undefined;
request2 (valid): cnt = 1; res = 1;
request3 (invalid): cnt = 0; res = 1;
request4 (valid): cnt = 1; res = 0;

All I want to do is to return the main function with true if "cnt" = 1 and false if "cnt" = 0, either with help of a global variable or using another method.

function validateHeaders(request) {
    if (request.headers.username && request.headers.deviceid) {

        if (...) {
            function getResult(callback) {
                db.tokens.count({...
                }, function (err, cnt) {
                    if (err) {
                        console.log(err);
                    } else {
                        callback(cnt);
                    }
                });
            }

            getResult(function (cnt) {
                res = cnt;
                console.log({
                    count: cnt
                });
            });

            console.log({
                result: res
            });
        } else {
            return false;
        }
    } else {
        return false;
    }
}

You can't return a meaningful value like that from a function that performs asynchronous, non-blocking operations inside. What you need to do instead is pass in a callback:

function validateHeaders(request, cb) {
  if (request.headers.username && request.headers.deviceid) {
    if (...) {
      db.tokens.count({
        // ...
      }, function (err, cnt) {
        if (err) {
          cb(err);
        } else {
          cb(null, cnt === 1);
        }
      });
      return;
    }
  }
  cb(null, false);
}

Then use it like:

validateHeaders(req, function(err, success) {
  if (err) throw err; // TODO: improve error handling
  console.log(success);
});

if you want to use the return value of callback function of nodejs. You can't use it in sync style. you can obey convention of nodejs.

function validateHeaders(request, cb) {
    if (request.headers.username && request.headers.deviceid) {

        if (...) {
            function getResult(callback) {
                db.tokens.count({...
                }, function (err, cnt) {
                    callback(err, cnt);
                });
            }

            getResult(function (err, cnt) {
                if (err) {
                    cb(err);
                } else {
                    if (cnt === 0)
                        cb(null, false);
                    else
                        cb(null, true);                    
                }
            });
        } else {
            cb(null, false)
        }
}

you can use the callback result. Notice: do not use return in async function. use callback to transfer the value. the callback function of nodejs style has 2 arguments. The first is err, the second is result.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM