将变量传递给命名回调

时间:2015-04-15 00:31:41

标签: javascript callback

好的,让我们保持简单,我有以下内容:

function loopDaLoop(){
    for (var i = 0; i < tempItemsLength; i++) {
        var product = tempItems[i];
        dust.render('product', product, addProductOrFinish);
    }
}

我想在回调函数

中获取i的当前值
function addProductOrFinish(err, out) {
   console.log(i); // undefined
}

我知道这很简单,我真的...帮忙?

编辑: 我知道我应该使用一个闭包,所以我尝试了并且失败了:

(function(i){
    dust.render('product', product, addProductOrFinish);
};(i)

1 个答案:

答案 0 :(得分:2)

有几种不同的结构可用于解决此问题。最简单的方法是使用.bind()将所需参数添加到函数调用中。

function loopDaLoop(){
    for (var i = 0; i < tempItemsLength; i++) {
        var product = tempItems[i];
        dust.render('product', product, addProductOrFinish.bind(null, i));
    }
}

function addProductOrFinish(i, err, out) {
   console.log(i);
}

如果这很重要,这将导致this的值在addProductOrFinish中更改。如果是这样,你也可以解决这个问题,但事情并非如此简单。


这是使用闭包的另一种方法,该闭包返回一个函数并保留this的值,以防dust.render()设置:

function loopDaLoop(){
    for (var i = 0; i < tempItemsLength; i++) {
        var product = tempItems[i];
        dust.render('product', product, getAddProductOrFinish(i));
    }
}

function getAddProductOrFinish(loopArg) {
     return function(err, out) {
         return addProductOrFinish.call(this, loopArg, err, out);
     }
}

function addProductOrFinish(i, err, out) {
   console.log(i);
}

或者,如果addProductOrFinish可以是内联函数,那么它可以使用您尝试过的IIFE类型结构:

function loopDaLoop(){
    for (var i = 0; i < tempItemsLength; i++) {
        var product = tempItems[i];
        (function(i) {
            dust.render('product', product, function(err, out) {
                console.log(i);
                // rest of your addProductOrFinish logic here
            });
        )(i);
    }
}