在express中
可以正常写入文件,写入文件名也是正确的
但是
console.log(imgName)
每次输出的结果都是一样的 都是最后的文件名
为什么呢,
要怎么解决比较好
router.post('/uploadImages', function(req, res){
var form = new multiparty.Form();
form.parse(req, function(err, fields, files){
//获得浏览器提交的图片数据
var imgDatas = fields.editImg;
//遍历图片数据,然后写入到后台
for(let i = 0; i < imgDatas.length; i++){
elem = imgDatas[i].replace(/^data:image\/\w+;base64,/, '');
var dataBuffer = new Buffer(elem, 'base64');
var imgName = path.join(__dirname,'../public/tempImg/') +'img' + Date.now() + i + '.png';
//写入文件
fs.writeFile(imgName, dataBuffer, function(err){
if (err) {
console.log(err);
}else{
console.log(imgName);
}
})
}
})
})
Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
michael_cai的回答很准确了,我这里补充一下代码,如果你是不理解闭包的意思的话,实际是这样的
那么如何保存声明回调时的上下文能,最直接的办法就是将整个方法放入闭包中
因为闭包可以"保存"调用时的参数,将这个参数"私有化",注意,我这里的解释都是比较通俗的
准确的解释请参阅更多详细资料,这个不是闭包的定义,那么代码应该改为
因为你的imgName不是通过参数传进去的,实际上log的都是同一个,加一个闭包就好了。
大家都已经给出解决方案(
HOW)了,我来说说为什么(WHY)吧。声明一个函数(
function)的时候,函数会捕获外部变量的引用,注意,是引用,而不是值。下面是例子
执行上面的代码,你会得到下面的结果:
看上起很不符合直觉,其实不然,注意我上面说过的 “函数会捕获外部变量的引用”,在每一次循环里面生成的匿名函数中,捕获的是
foo的引用,而不是foo的值。你可能会发现我上面的代码和你的实际情况有所出入,下面使用和你实际情况相似的代码。其实也就删掉
for循环外面的var foo;并把var关键字加到循环内部的foo前面。你可以运行一下代码,发现和上面的运行结果是一样的,接下来就带来另一个问题了,我不是在每次循环的时候重新声明了foo吗,为什么还是会这样。Really? 其实真的重新声明了吗?
我们用下面的代码做个试验:
在这里,我定义了
print这个函数,用于打印foo的值,下面我用var关键字再次声明了foo,print函数仍旧可以很好的工作!oops!。再次声明的foo和第一次声明的foo的引用是一样的。所以呢?
让我们回到刚才的代码:
你可能又有疑问了,我不是在
for循环中声明的吗?这里可能有个关于作用域的误区,for循环并不会生成新的作用域。所以上面的代码等价于:for循环不会生成新的作用域,但是函数可以,使用立即执行函数表达式(IIFE)包装一下:执行结果:
Nice Work!
其实使用
ES6的let可以更简单,只需要把var换成let就好了:执行结果:
具体可参看:ECMAScript 6 入门 - let和const命令
这事用async就简单太多了