闭包在循环里面出现诡异现象。。
发布于 7 年前 作者 maxxfire 3200 次浏览 来自 问答

var fs = require(‘fs’); var files = [‘file1’, ‘file2’, ‘file3’];

//循环3次,检测3个文件的属性: var k = 0; while (true) { if (k++ > 2) { break; }

var file = files.shift();

//检测文件属性:
var path = '/var/dir/' + file;
console.log('File: %s', file);		//外层打印
fs.stat(path, function(err, stats) {
    console.log('%s stat invoke.', file);	//内层打印
});

}

预期打印结果: File: file1 File: file2 File: file3 file1 stat invoke. file2 stat invoke. file3 stat invoke.

但实际结果: File: file1 File: file2 File: file3 file3 stat invoke. file3 stat invoke. file3 stat invoke.

这是什么情况,全部返回file3。 如果不能把闭包外层的变量file带进闭包里面,那怎么搞,谁还敢写代码。。

6 回复

有一种东西叫IIFE

@nullcc 按正常理解,3次循环应该创建3个不同的file变量,然后每个分别进入fs.stat闭包中,这样才能输出预期的结果,可是它没有。。。

两种解决方案。

1.调用异步方法时用立即执行函数表达式,手动传一个参数进去:

(function(filename){
	// 你的异步代码
})(filename)

2.for循环里面用let声明索引变量(需要ES6)。

@maxxfire

fs.stat(path, function(err, stats) {
	console.log('%s stat invoke.', file);	//内层打印
});

换成

function (fileIn) {
	fs.stat(path, function(err, stats) {
		console.log('%s stat invoke.', fileIn);	//内层打印
	});
}(file);

才是闭包,你这个不叫闭包

这个不是闭包吧。。。

谢楼上,学习了。。

回到顶部