在javascript中处理循环,只有最后一项受到影响?

时间:2014-03-16 14:16:18

标签: javascript closures

我正在处理处理图像处理的gm npm模块。我有这个代码。

for(i=0;i < 4;i++){
    gm("www/img/" + image[i]).crop(550, 406, 0, 0).write(function(err) {
         console.log(this.outname + " created  ::  " + arguments[3]); //success
    });
}

这个循环意味着循环遍历图像阵列并裁剪每张照片,但它只裁剪最后一张。我认为它可以执行函数调用和回调,但在该级别尚未提升。

2 个答案:

答案 0 :(得分:7)

将您的代码更改为:

for (var i = 0; i < 4; i++) {
  (function (i) {
    gm("www/img/" + image[i]).crop(550, 406, 0, 0).write(function(err) {
         console.log(this.outname + " created  ::  " + arguments[3]); //success
    });
  }).call(this, i);
}

否则每次调用回调时i的值都为3。

答案 1 :(得分:3)

你需要在变量

上创建一个“闭包”

Js有功能范围。

for (i = 0; i < 4; i++)
{
    (function (a)
    {
        gm("www/img/" + image[a]).crop(550, 406, 0, 0).write(function (err)
        {
            console.log(this.outname + " created  ::  " + arguments[3]); //success
        });
    }).call(this,i)
}

that=this;

for (i = 0; i < 4; i++)
    {
        (function (a)
        {
            gm("www/img/" + image[a]).crop(550, 406, 0, 0).write(function (err)
            {
                console.log(that.outname + " created  ::  " + arguments[3]); //success
            });
        })(i)
    }

编辑:

此外 - 我会保持arguments的引用,因为现在,在IIFE之后 - 参数正在发生变化。

您可以通过以下方式保留arguments

var args= Array.prototype.slice.apply(arguments)

示例:

function g()

{
for (i = 0; i < 4; i++)
    {
        (function (a)
        {
           console.log(arguments); //huh ? arguments are not a,b,c !!! anymore
        })(i);
    }
}


g('a','b','c') // 0,1,2,3

因此你需要在IIFE之后继续引用他们改变的参数。