如何使用基于索引的参数创建函数数组

时间:2014-01-06 04:28:02

标签: node.js asynchronous

我有一组通过async.series()函数运行的函数,它将我碰巧存储在数组中的值作为参数。

params = [ {id: 1, name: "Two tires fly. Two wail."},
           {id: 2, name: "Snow-Balls have flown their Arcs"},
           {id: 3, name: "A beginning is the time for taking the most delicate care"}
         ];
async.series(
[   function(callback) {
        myFunction(callback, params[0]);
    },
    function(callback) {
        myFunction(callback, params[1]);
    },
    function(callback) {
        myFunction(callback, params[2]);
    },
]);

显然,数组要大得多,将它们包装成循环会很方便:

var functionsArray = [];

for (var i = 0; i < params.length; ++i) {
    functionsArray.push(
        function(callback) {
           myFunction(callback, params[i]);
        }
     );
 }

 async.series(functionsArray);

唉,这种技术让jshint对于在数组中定义一个函数感到不满,我明白为什么它不起作用。 i在通话时将是固定值,不会被捕获为值。

如何创建一组参数在数组中的函数,这样我就不必明确定义每一个函数。

我愿意使用async中的其他设施。此外,这些函数是高度异步的,因此使用async.series()

的原因

2 个答案:

答案 0 :(得分:1)

您可以本地化&#39; i&#39;通过在anon中包装你想要的东西。自我调用功能:

params = [ {id: 1, name: "Two tires fly. Two wail."},
           {id: 2, name: "Snow-Balls have flown their Arcs"},
           {id: 3, name: "A beginning is the time for taking the most delicate care"}
];

var currentlyFinished = 0;
function finished () {
    currentlyFinished ++;
    if( currentlyFinished == params.length ) {
        //
        // you will end up here after all the params have been run thru your function
        // If you need a list sorted after all the callbacks, you'd do that here
        // 
    }
}
for (var i = 0; i < params.length; ++i) {
    (function(currentIndex) {  // 'i' becomes 'currentIndex', which is local to the anon. function
        myFunction( params[currentIndex], function () {
            finished ();
        });
    })(i);  // here is where you 'call' the anon. function, passing 'i' to it
 }

作为一个注释,我从来没有使用过异步库。但它确定了。看起来它是一个有用的工具,有很多其他方法可以用更简单的方式做到这一点;我喜欢先按照我的方式解决问题,理解它们,一旦我明白了,lib就可以完成繁重的任务。

答案 1 :(得分:1)

您可能想要async.eachasync.eachSeries(第一个并行工作):

async.eachSeries(params, function(param, callback) {
  myFunction(callback, param);
}, function(err) {
  // Put code that needs to run when its all finished here
})
但是,它可能更容易。如果myFunction最后使用回调参数(这是node.js中的标准),则可以删除额外的匿名函数:

async.eachSeries(params, myFunction, function(err) {
  // Put code that needs to run when its all finished here
})

如果使用回调最后签名编写函数,它们将更有可能与node.js库很好地协作。

  

唉,这种技术让jshint对于在数组中定义函数感到不满,我明白为什么它不会起作用。

我认为你的意思是&#34;在循环中定义一个函数&#34;?如果是这样,这是因为定义函数相当昂贵,并且jshint不鼓励 - 不是因为它不能工作。它也可能已经认识到i将不是您想要的 - 它将是最终值,因为javascript闭包的工作方式。通常,您应该避免在循环中定义函数,但是您可以避免使用IIFE的i问题(立即调用的函数表达式):

for (var i = 0; i < params.length; ++i) {
    (function(i) {
        functionsArray.push(
            function(callback) {
                myFunction(callback, params[i]);
            }
        );
    })(i);
}