JavaScript variables hoisting in nodejs/async

允我心安 提交于 2019-12-08 10:44:16

问题


In the next example I don't have access to variable "locals" inside the functions "fetcher", "parser" and "saveToDb".

var parser = require('parser.js');
var fetcher = require('fetcher.js');
var saveToDb = require('models/model.js');
var async = require('async');


function task() {
    var locals = []    //<-- declared here
    async.series([
        fetcher,    //<--  can not access "locals"
        parser,     //<--  can not access "locals"
        saveToDb    //<--  can not access "locals"
    ],
            function (err) {
                if (err) return callback(err);
                callback(null);
    });
}

In the next example "local"s is accessible. I just copyed the functions declarations from the requested modules, and pasted them straight inside "async.series".

var async = require('async');

function task() {
    var locals = []    //<-- declared here
    async.series([
        function(callback) {// <-- can access "locals"},  
        function(callback) {// <-- can access "locals"},
        function(callback) {// <-- can access "locals"}
    ],
            function (err) {
                if (err) return callback(err);
                callback(null);
    });
}

While this works - I do want to keep my code modular. How can I fix that ? Or - what I forgot here about the fundamentals of JavaScript ?

Thanks.


回答1:


In the first example, the callbacks live in another scope so can't access locals.

You could create partial functions that get the locals variable passed as first argument, but that would require you to rewrite your callbacks.

// creating a partial
async.series([
  fetcher.bind(fetcher, locals),
  parser.bind(parser, locals),
  saveToDb.bind(saveToDb, locals)
], ...)

// new function signatures
function fetcher (locals, callback) { ... }
function parser  (locals, callback) { ... }
function saveToDb(locals, callback) { ... }



回答2:


You can have the 3 mentionned functions defined like this :

function fetcher(locals) {
  return function _fetcher(callback) {
    // this function body will have access to locals
  }
}

and rewrite your code as:

function task() {
    var locals = []    //<-- declared here
    async.series([
        fetcher(locals),    //<--  can now access "locals"
        parser(locals),     //<--  can now access "locals"
        saveToDb(locals)    //<--  can now access "locals"
    ],
            function (err) {
                if (err) return callback(err);
                callback(null);
    });
}



回答3:


IF i understand your problem correctly this is a javascript 101 question.

fetcher can be a factory that creates a concrete fetcher.

var fetcher = function(locals){
 locals=locals||[] // optional , assign a default , whatever ...
 return function(){
   //do some operation with locals.
   doSomething(locals);
 }
}

then in your script

 async.series([
        fetcher(locals),    //<--  will return the callback to use
        parser(locals),     //<--  will return the callback to use
        saveToDb(locals)    //<--  will return the callback to use
    ],

i believe it is a kind of currying.



来源:https://stackoverflow.com/questions/16986660/javascript-variables-hoisting-in-nodejs-async

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!