我知道这可能是重复但我无法弄清楚如何做到(相信我,我已经搜索过,我试图摆弄代码)。我有以下代码,它构建了一个可以拖放到应用程序中的文件表。
function CreateTrackTable (data, length) {
var fs = require('fs'),
mm = require('musicmetadata'),
i = 0;
for (i; i < length; ++i) {
var mimeType = data.dataTransfer.files[i].type;
if (mimeType == "audio/mp3" || mimeType == "audio/x-m4a"){
FilePath = data.dataTransfer.files[i].path;
var parser = mm(fs.createReadStream(FilePath));
parser.on('metadata', function (result) {
if (result.picture.length == 0) {
$("#track-table").append('<tr path="'+ FilePath +'"><td></td></tr>');
}else{
var picture = base64ArrayBuffer(result.picture[0].data);
$("#track-table").append('<tr path="'+ FilePath +'"><td></td></tr>');
}
});
}
}
}
问题是FilePath变量是可访问的,但是它“打印出来”总是相同的路径,而不是循环i所遵循的路径。
应用程序使用nodo-webkit构建,一切都很有效,这是我唯一无法弄清楚的问题。
感谢您的帮助!
答案 0 :(得分:3)
在循环内创建的每个函数都关闭相同的FilePath
(即它们不会各自得到它们自己的副本),这意味着它们每个都会看到变量执行时所具有的任何值。为了使这项工作符合您的预期,您需要对其进行排列,以便他们做每个都获得自己的副本。由于JavaScript变量的范围限定为最近的封闭函数,因此将函数创建包装在一个立即调用的函数中,该函数接收所需的值作为参数:
(function(FilePath) {
parser.on('metadata', function (result) {
if (result.picture.length == 0) {
$("#track-table").append('<tr path="'+ FilePath +'"><td></td></tr>');
} else {
var picture = base64ArrayBuffer(result.picture[0].data);
$("#track-table").append('<tr path="'+ FilePath +'"><td></td></tr>');
}
});
})(FilePath);
在这种情况下,每个新函数都会关闭一个新的FilePath
,从而产生想要的结果。