执行 .Then() 承诺 NodeJS

Posted

技术标签:

【中文标题】执行 .Then() 承诺 NodeJS【英文标题】:Execute .Then() promise NodeJS 【发布时间】:2020-07-01 16:06:15 【问题描述】:

我试图弄清楚如何使用“.then”调用 Promise,以便我可以继续在返回的 Promise 输出上执行其他功能。我已经确认正在使用的功能按预期工作,但在观看视频和其他 SO 示例之后,仍然很难让它工作。见下sn-p:

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');

我不断收到“(节点:1144376)UnhandledPromiseRejectionWarning:ReferenceError:在初始化之前无法访问'promiseToken'”上面的代码块采用文件名数组并循环遍历每个元素并提取文件名的部分并连接这些部分我需要创建一个新文件名的每个元素名称。同样,该功能有效并经过测试。当我尝试通过“.then()”调用“readZip()”的返回输出时不起作用。我需要让这部分工作,这样我才能继续编写脚本的其余部分。我是 NodeJS 和 javascript 的新手,任何帮助都将不胜感激,因为我尝试过的视频或示例似乎都不起作用.....

【问题讨论】:

您的意思是将return promiseToken; 放在readZip 的末尾吗?目前您正在从new Promise 构造函数回调中重新调整 你永远不会兑现你的承诺!您应该将resolve/rejectreadFile 中的data/err 放在一起,然后将其余逻辑放在then 子句中,使用JSZip.loadAsync 的承诺链 【参考方案1】:

如果你使用fs.promises 接口,这会简单很多,其中fs.promises.readfile() 已经是一个返回承诺的版本:

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);
    
)

【讨论】:

【参考方案2】:

你需要:

    在您的 readZip 函数中返回承诺(目前您没有这样做) 用您想要的数据解决承诺(目前您根本没有解决) 在 .then 中使用该数据,如下所示:
readZip().then((data) => 
   // Use the data to do whatever you want
);

【讨论】:

添加:“const promiseToken = new Promise((data, err) => ”并在构造函数之外返回promise。调用上面提到的函数,但它没有出现承诺中有任何数据: readZip().then((data) => console.log(data);); 您需要用数据解析,我会将 files.forEach 迭代移动到 .then 并返回 resolve(files) 【参考方案3】:

您似乎漏掉了一行,并且从 Promise 的构造函数返回 promiseToken,而不是从 readZip 的定义中返回。因此,readZip 不返回任何内容,而您会得到一个 undefined 值。

把它移到正确的地方,你应该没问题:

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
;

【讨论】:

最初尝试此配置时,我无法获得 JSZip.loadAsync(data).then(functionn (zip) forEach 创建的循环的输出。如何包含包含“files.forEach”循环?除此之外,这个解决方案确实有效,只是不像我希望的那样不幸......

以上是关于执行 .Then() 承诺 NodeJS的主要内容,如果未能解决你的问题,请参考以下文章

打破承诺链 - 停止执行下一个“then”

NodeJs分页,递归承诺问题

在javascript承诺中执行的顺序是什么

猫鼬承诺文档说查询不是承诺?

承诺等待得到解决而不返回

承诺执行条件