如何在for循环中迭代以下代码?

时间:2013-06-14 00:42:03

标签: javascript node.js

我有以下代码,它抓取6个URL中的一个,剥离文件名,创建文件路径,将图像文件保存到磁盘,然后将其发送到MongoDB GridFS。唯一不变的是图像尺寸:32px,64px,128px,256px,512px,1024px。 Bruteforce方法只是复制并粘贴此代码6次,你只能想象会是什么样的混乱。

如何将此代码置于for循环中,其中 32 将更改为 64 128 256 , 512 1024

var filename32 = image32.replace(/^.*[\\\/]/, '');
var filepath32 = path.join(__dirname, filename32);
var writestream32 = gfs.createWriteStream({ filename: filename32 });
var imageStream32 = request(image32).pipe(fs.createWriteStream(filepath32));

imageStream32.on('close', function() {
  fs.createReadStream(filepath32).pipe(writestream32);
  fs.unlink(filepath32);
});

更新。

好的,所以使用迭代方法无法解决这个问题。更多信息:node.js: while loop callback not working as expected TLDR :因为node.js和javascript是单线程的。

3 个答案:

答案 0 :(得分:1)

这样的东西?我不确定实际需要附加图像大小,我只是猜到了文件名。

for(var i=32; i <= 1024; i*=2) {
    var filename = image.replace(/^.*[\\\/]/, '') + i;
    var filepath = path.join(__dirname, filename);
    var writestream = gfs.createWriteStream({ filename: filename });
    var imageStream = request(image).pipe(fs.createWriteStream(filepath));

    imageStream.on('close', function() {
      fs.createReadStream(filepath).pipe(writestream);
      fs.unlink(filepath);
    });
}

答案 1 :(得分:1)

使用数组?我不确定我是否理解你的问题,因为这个解决方案看起来很傻......

// use this array to store file names(urls).
    var imagesName = new Array("32.png", "128.png", "256.png", "512.png", "1024.png");

for (var i = 0; i < imagesName.length; i++) {
    var filename = imagesName[i].replace(/^.*[\\\/]/, '');
    var filepath = path.join(__dirname, filename);
    var writestream = gfs.createWriteStream({ filename: filename });
    var imageStream = request(imagesName[i]).pipe(fs.createWriteStream(filepath));

    imageStream32.on('close', function() {
      fs.createReadStream(filepath).pipe(writestream);
      fs.unlink(filepath);
    });
}

答案 2 :(得分:0)

如果您所做的只是每次都加倍,则不需要数组。正如@ bitwiser的答案所示,计算两个权力是微不足道的。

但是之前的两个答案都有一个错误。他们使用filepath回调中的writestreamimageStream32.on('close')变量,但是,在for循环完成执行后异步调用此回调。因此,所有这些回调都使用这两个变量最后一次通过循环接收的最后一个值,而不是正确循环迭代中的正确值。

很容易解决这个问题:你只需要为每个循环迭代调用一个函数,而不是将代码直接放在循环体中。函数调用创建一个闭包,为每个图像单独保留这些变量,因此您将为每个图像编写和关闭正确的文件。

此外,您没有定义生成文件名的image32变量。你真的需要复杂的正则表达式吗?你不知道图像文件名应该是什么吗?我将假设文件名为'image32' ... 'image1024',但您当然可以轻松更改文件名。

所以代码看起来像这样:

function processImages( basename, minSize, maxSize ) {
    for( var size = minSize;  size <= maxSize;  size *= 2 ) {
        processImage( size );
    }

    function processImage( size ) {
        var filename = basename + size;
        var filepath = path.join( __dirname, filename );
        var writestream =
            gfs.createWriteStream({ filename: filename });
        var imageStream =
            request(image).pipe( fs.createWriteStream(filepath) );

        imageStream.on( 'close', function() {
          fs.createReadStream(filepath).pipe(writestream);
          fs.unlink(filepath);
        });
    }
}

processImages( 'image', 32, 1024 );