Javascript 函数中的链接承诺
我有一个小问题,如何以合理的方式创建承诺链,使makeZip函数首先添加所有必要的文件,然后创建zip,最后删除以前添加的文件?(makeZip函数还必须返回一个承诺)。在下面的示例中,我不在任何地方调用deleteFile,因为我不知道在哪里调用它。当我试图在addfile函数中调用它以在添加文件后立即删除文件时,不知为什么控制台显示了zip maked!先记录日志,然后删除文件Javascript 函数中的链接承诺,javascript,node.js,ecmascript-6,Javascript,Node.js,Ecmascript 6,我有一个小问题,如何以合理的方式创建承诺链,使makeZip函数首先添加所有必要的文件,然后创建zip,最后删除以前添加的文件?(makeZip函数还必须返回一个承诺)。在下面的示例中,我不在任何地方调用deleteFile,因为我不知道在哪里调用它。当我试图在addfile函数中调用它以在添加文件后立即删除文件时,不知为什么控制台显示了zip maked!先记录日志,然后删除文件 const deleteFile = (file, result) => { new Promise((
const deleteFile = (file, result) => {
new Promise((resolve, reject) => {
fs.unlink(`./screenshots/${file}`, (err) => {
if (err) return reject(err);
console.log(`${file} deleted!`);
return resolve();
});
});
};
const addFile = (file) => {
new Promise((resolve, reject) => {
try {
zip.addLocalFile(`./screenshots/${file}`);
console.log(`${file} added`);
return resolve();
} catch {
return reject(new Error("failed to add file"));
}
});
};
const makeZip = () => {
Promise.all(fs.readdirSync("./screenshots").map((file) => addFile(file)))
.then(() => {
return new Promise((resolve, reject) => {
try {
zip.writeZip(`./zip_files/supername.zip`);
console.log("zip maked!");
resolve();
} catch {
return reject(new Error("failed making zip"));
}
});
})
.catch((err) => console.log(err));
};
主要原因是您没有返回在函数调用中实例化的承诺。另外,我还有一些很酷的建议,可以提高代码的清洁度 [提示]:曾经检查过
NodeJS
util
包中的promisify
函数,它随node一起提供,非常方便地将需要回调作为参数的函数转换为承诺返回函数。我将在下面进行演示
// so I will work with one function because the problem resonates with the rest, so
// let us look at the add file function.
// so let us get the promisify function first
const promisify = require('util').promisify;
const addFile = (file) => {
// if addLocalFile is async then you can just return it
return zip.addLocalFile(`./screenshots/${file}`);
};
// okay so here is the promisify example, realized it wasn't applicable int the function
// above
const deleteFile = (file, result) => {
// so we will return here a. So because the function fs.unlink, takes a second arg that
// is a callback we can use promisify to convert the function into a promise
// returning function.
return promisify(fs.unlink)(`./screenshots/${file}`);
// so from there you can do your error handling.
};
现在,让我们把它们放在最后一个函数中,即,makeZip
const makeZip = () => {
// good call on this, very interesting.
Promise.all(fs.readdirSync("./screenshots").map((file) => addFile(file)))
.then(() => {
return zip.writeZip(`./zip_files/supername.zip`);
})
.then(() => {
//... in here you can then unlink your files.
});
.catch((err) => console.log(err));
};
有了这些建议,一切都会好起来的,希望能解决…谢谢大家的提示,解决方案变得简单多了,只需使用fs.unlinkSync方法而不是异步fs.unlink
const deleteFile = (file) => {
try {
fs.unlinkSync(`./screenshots/${file}`);
console.log(`${file} removed`);
} catch (err) {
console.error(err);
}
};
const addFile = (file) => {
try {
zip.addLocalFile(`./screenshots/${file}`);
console.log(`${file} added`);
deleteFile(file);
} catch (err) {
console.error(err);
}
};
const makeZip = () => {
fs.readdirSync("./screenshots").map((file) => addFile(file));
zip.writeZip(`./zip_files/supername.zip`);
console.log("zip maked!");
};
我认为您的程序无效,为什么
addFile()
返回承诺对象?zip.addLocalFile()
和zip.writeZip()
是异步的吗?如果是这样,您是否忘记了在zip.addLocalFile()
和zip.writeZip()
之前等待?zip.addLocalFile
和zip.writeZip
实际上是异步的?如果是,您(在调用后立即解决,而不是在调用结束时解决-他们应该进行回调?),如果不是,您根本不需要将它们包装在new Promise
中。即使他(@Vasper)忘记返回每个函数的承诺,我只会在顶部承诺unlink
一次-const unlink=promisify(fs.unlink);代码>