あいつの日誌β

働きながら旅しています。

はじめての即時関数

mongo への問い合わせをするときに複数の collection への問い合わせをする処理を考えていたら async 使ったらいけるんじゃね?と思ったので次のようなスクリプトを書いてみた

var async = require('async');

var tasks = [], cols = ['hoge', 'fuga', 'piyo'];
    
for (var i = 0, len = cols.length; i < len; i ++) {

    var _col = cols[i]; 
    tasks.push(
        function(next) { 
            console.log('searchDb('+_col+')');
            next(null);
        }   
    );  
}

async.series(tasks, function(err) {
    console.log('end');
});

実行。残念...

:!node %                                                                      
searchDb(piyo)
searchDb(piyo)
searchDb(piyo)
end

tasks に挿入されている無名関数は同じ _col を参照しているんですが、実行される段階では既に piyo が代入されています。

そこで即時関数

即時関数なぞ使うケースないから覚える必要ないやと思っていたんですが、なぜか覚えててここで即時関数を使えば問題を解決できる事に気がついた。

var async = require('async');

var tasks = [], cols = ['hoge', 'fuga', 'piyo'];
    
for (var i = 0, len = cols.length; i < len; i ++) {

    var _col = cols[i]; 
    tasks.push(
        (function(col) {
            return function(next) { 
                console.log('searchDb('+col+')');
                next(null);
            };  
        })(_col)
    );  
}

async.series(tasks, function(err) {
    console.log('end');
});

実行

:!node test.js
searchDb(hoge)
searchDb(fuga)
searchDb(piyo)
end

やったね!