Node.js中的Promise.all没有't调用then函数
Promise.all in Node.js doesn't call the then function
我学习了如何使用Node和Ecmascript 6。
我的脚本的目的是重命名目录中的png文件列表。我只想重命名png文件(假设也有jpg),并在最后显示重命名的文件数。由于Node的非阻塞性,它并不那么明显,我决定利用这个机会来发现ES6的承诺。
'use strict';
const fs = require('fs-extra');
const dir = '/Users/toto/Desktop/png/';
const suffix = '_IMAGE.';
const regex = /(.*)'.(png)$/;
var nbFiles = 0;
// Rename a png file with a suffix
var renameFile = (filename) => {
return new Promise((resolve, reject) => {
if(regex.test(filename)){
let newFileName = filename.replace(regex, '$1' + suffix + '$2');
fs.rename(dir + filename, dir + newFileName, (err) => {
let msg = filename + ' => ' + newFileName;
if (err) {
console.log('KO : rename of ' + msg);
reject(err);
}
console.log('OK : rename of ' + msg);
resolve(nbFiles++);
});
}
});
};
// Read files in a directory and call renameFile + display number of files renamed
fs.readdir(dir, (err, files) => {
if(err) return console.error(err);
var promise = Promise.all(
files.map(renameFile)
).then(function(nb){
console.log('Number of files renamed : ', nb);
}).catch(function(err){
console.log('Error ', err);
});
});
预期的结果是重命名文件,并看到消息Number of files renamed。
我重命名了文件,但我看不到任何消息(关于then或catch调用)。有些地方出了问题,但调试会话对我没有帮助。
谢谢你的帮助!
PS:我的环境是Node 5.10和OS X 10.11。
问题是,当regex
与filename
不匹配时,您正在创建一些永远挂起(永远无法解决)的承诺。Promise.all
将无限期地等待他们。
您应该始终在尽可能低的级别上promisify——在您的情况下是fs.rename
和fs.readdir
——并且在处理"旧"回调API的函数中不放入其他代码。没有应用程序逻辑,没有字符串串联,没有日志记录,什么都没有。
function rename(from, to) {
return new Promise((resolve, reject) => {
fs.rename(from, to, (err, res) => {
if (err) reject(err);
else resolve(res);
});
});
}
function readdir(from, to) {
return new Promise((resolve, reject) => {
fs.readdir(from, to, (err, res) => {
if (err) reject(err);
else resolve(res);
});
});
}
(如果这看起来是重复的,那就是写一个辅助函数,或者使用promise库中的一个)
有了这些,你现在可以正确地(更容易地)实现你的脚本:
const dir = '/Users/toto/Desktop/png/';
const suffix = '_IMAGE.';
const regex = /(.*)'.(png)$/;
readdir(dir).then(files =>
Promise.all(files.map(filename => ({
from: dir + filename,
to: dir + filename.replace(regex, '$1' + suffix + '$2')
})).filter(r => r.from != r.to).map(r => {
let msg = r.from + " => " + r.to;
return rename(r.from, r.to).then(() => {
console.log("OK: " + msg);
}, err => {
console.log("KO: " + msg);
throw err;
});
}));
).then(function(res) {
console.log('Number of files renamed : ', res.length);
}).catch(function(err) {
console.error('Error ', err);
});
相关文章:
- AngularJS因果报应测试规范承诺未解析,且未调用.then()
- “未捕获(在承诺中)”在获取“then”方法中调用拒绝函数时
- 使用promise.then时,是否可以保留在单击事件调用堆栈中
- Node.js中的Promise.all没有't调用then函数
- Dispatch()调用一个函数,但是.then()不调用;我不在React Redux上工作
- 未捕获的类型错误:无法调用未定义的方法“then”
- 未捕获的类型错误:调用函数时无法读取未定义的属性“then”
- Javascript 承诺 .catch 仍然调用 final variable.then
- 获取类型错误:无法在 angularjs 控制器中调用未定义的方法 'then'
- Promise/A+ with chain then() 回调用例
- TypeError:无法调用未定义的 Angularjs 的方法 'then'
- 问.js节点承诺.“套接字”上缺少错误处理程序.类型错误:无法调用未定义的方法“then”
- 如何包装需要异步调用的复杂 if-then 语句
- 如何与 JQuery WHEN 和 THEN 同步两个骨干获取调用
- 第一个角度$http POST 落入 .then 错误路径,即使 REST 调用成功
- Bluebird 不会调用 then(),即使使用之前工作的代码也是如此
- Promise A+实现:当调用then()并且Promise仍然挂起时该怎么办
- 等待所有异步ajax调用完成,并延迟.when().then(),未调用then()中的任务
- 在Dart中.callmethod返回后,我如何调用.then ?
- Promises是调用`.then`后执行副作用所需的A+Promises吗