将变量传递给命名回调

Passing variable into named 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)

有几种不同的结构可以用来解决这个问题。最简单的是使用 .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 中发生变化。如果是这样,您也可以解决这个问题,但这并不那么简单。


这是另一种使用闭包的方法,该闭包 returns 一个函数并保留 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);
    }
}