问题
I am trying to figure out how to call a Promise using ".then" so I can continue performing other functions on the return Promise output. I have confirmed the function being used works as expected, but after watching videos and other SO examples am still having a hard time getting this working. See below snippet:
const fs = require('fs');
const JSZip = require('jszip');
const directoryFile = fs.readdirSync('./zipped');
//console.log(directoryFile);
var zip = new JSZip();
var dir = ('./zipped/');
const readZip = async () => {
const promiseToken = new Promise((resolve, reject) => {
fs.readFile((dir + directoryFile), function (err, data) {
if (err) throw err;
JSZip.loadAsync(data).then(function (zip) {
const files = Object.keys(zip.files);
console.log(files);
files.forEach((files) => {
const pkgName = files.substring(files.indexOf("_", files.indexOf("_")) + 1, files.lastIndexOf("_"));
const fileExt = files.split('.').pop();
const pkgExtract = (pkgName + "." + fileExt);
});
})
});
return promiseToken;
});
};
console.log('Program Starts');
readZip().then((promiseToken) => {
console.log(promiseToken.join(','));
});
console.log('Program Ends');
I keep getting "(node:1144376) UnhandledPromiseRejectionWarning: ReferenceError: Cannot access 'promiseToken' before initialization" The above code block take an array of file names and loops through each element and extracts portions of the file name and joins the portions of each elements name that I need to create a new file name. Again, the function works and is tested. What is not working is when I try to call the return output of "readZip()" via ".then()". I need to do get this portion working so I can continue on with the rest of the script. I am new to NodeJS and Javascript and any assistance would be appreciated as none of the videos or examples I have attempted seem to be working.....
回答1:
You seem to have missed a line, and are returning promiseToken
from the promise's constructor instead of from the definition of readZip
. Therefore, readZip
returns nothing, and you get an undefined
value.
Move it to the correct place and you should be fine:
const readZip = async () => {
const promiseToken = new Promise((resolve, reject) => {
fs.readFile((dir + directoryFile), function (err, data) {
if (err) throw err;
JSZip.loadAsync(data).then(function (zip) {
const files = Object.keys(zip.files);
console.log(files);
files.forEach((files) => {
const pkgName = files.substring(files.indexOf("_", files.indexOf("_")) + 1, files.lastIndexOf("_"));
const fileExt = files.split('.').pop();
const pkgExtract = (pkgName + "." + fileExt);
});
})
});
});
return promiseToken; // Moved here
};
回答2:
You need to:
- return the promise in your readZip function (currently you are not doing that)
- resolve the promise with your desired data (currently you are not resolving at all)
- Use that data in the .then like so:
readZip().then((data) => { // Use the data to do whatever you want });
回答3:
This can be a lot simpler if you use the fs.promises
interface where fs.promises.readfile()
is already a version that returns a promise:
const readZip = async () => {
const data = await fs.promises.readFile(dir + directoryFile);
const zip = await JSZip.loadAsync(data);
const files = Object.keys(zip.files);
console.log(files);
return files;
};
readZip.then(files => {
for (file of files) {
const pkgName = file.substring(file.indexOf("_", file.indexOf("_")) + 1, file.lastIndexOf("_"));
const fileExt = file.split('.').pop();
const pkgExtract = pkgName + "." + fileExt;
console.log(pkgExtract);
}
})
来源:https://stackoverflow.com/questions/60775523/execute-then-promise-nodejs