【问题标题】:nodejs run functions back to backnodejs 背靠背运行函数
【发布时间】:2021-09-26 03:32:14
【问题描述】:

我正在编写一个小的 nodejs 脚本来从另一个文件夹复制文件,修改一些文本并缩小内容。

根据我的研究,似乎有一个名为async 的模块,可以通过该模块一一调用。但我正在尝试如何在不安装任何模块的情况下做同样的事情(作为学习的一部分)。

我是这个 Promise/async 世界的新手。但我无法让它按预期顺序工作。 有人可以帮忙吗?

function updateText( textList ){
    return new Promise(function(resolve, reject){

        var folders = [ 'includes/lr', 'includes/vc' ];
        var acceptedFileTypes = ['php', 'js', 'css'];
    
        folders.forEach(function(dir){
            files = walk(dir);
            files.forEach( function ( file ) {

                fs.readFile(file, 'utf8', function (err,data) {
                    
                    fileType = file.split('.').pop();
                    if(!acceptedFileTypes.includes(fileType)){
                        return;
                    }

                    console.log('Editing - ' + file);

                    if (err) {
                      return console.log(err);
                    }
    
                    for(text in textList){
                        data = data.replace(new RegExp(text, 'g'), textList[text]);
                    }
    
                    fs.writeFile(file, data, 'utf8', function (err) {
                        console.log('Written file - ' + file);
                       if (err) return console.log(err);
                    });
    
                });
    
            });
        });

        console.log('Resolving')
        resolve();

    });
}

function minifyJS(){

    return new Promise(function(resolve, reject){
        minify('includes/vc/js/script-front.js').then(function(data){
            console.log('Minifying file - ');
            fs.writeFile('includes/vc/js/script-front.min.js', data, 'utf8', function (err) {
                if (err) return console.log(err);
                resolve();
             });
        });
    });

}

updateText({
    'qwerty': 'hello',
})
.then(function(r){
    minifyJS().then(function(){
        console.log('# Done');
    });
})

输出 - 事情到处都是,而不是按顺序排列,尽管只有在编辑文件后才会解决承诺。

在这里,我期待所有编辑首先完成,然后写入,最后缩小。

Resolving
Editing - includes/lr/css/style.css
Editing - includes/vc/css/style.css
Editing - includes/vc/js/script-front.js
Editing - includes/vc/js/script-front.min.js
Minifying file -
Editing - includes/vc/js/script.js
Editing - includes/lr/js/script.js
Editing - includes/vc/index.php
Editing - includes/lr/index.php
Written file - includes/lr/css/style.css
Written file - includes/vc/css/style.css
Written file - includes/vc/js/script-front.js
Written file - includes/vc/js/script.js
Written file - includes/lr/js/script.js
Written file - includes/vc/js/script-front.min.js
# Done
Written file - includes/vc/index.php
Written file - includes/lr/index.php

【问题讨论】:

    标签: node.js asynchronous promise


    【解决方案1】:

    似乎有一个名为 async 的模块,可以通过它一个一个地调用函数。但我正在尝试如何在不安装任何模块的情况下做同样的事情(作为学习的一部分)。

    async/await 不需要加载任何模块,并且可作为从 NodeJS 8.0.0 开始的 NodeJS 运行时的一部分使用

    我看到fs.readFilefs.writeFile的用法,它们都使用了回调函数。

    一旦fs.readFile/fs.writeFile 完成任务,就会调用该回调函数。

    fs.readFilefs.writeFile 的调用将放在event-loop 上,并且不能保证按照添加它们的顺序完成。 为了演示事件循环的阻塞,您可以使用来自fs 模块的同步调用

    我建议重构代码以使用util.promisify,这将允许fs.readFilefs.writeFile 被“承诺”,然后可以与async/await 一起使用。

    const listOfFilesRead = await readFiles
    await writeFiles(listOfFilesRead)
    await minify
    
    • readFiles 将是一个声明的async 函数,它在fs.readFile 上使用util.promisify,返回一个data 数组以在writeFiles 中使用
    • writeFiles 将是一个声明的async 函数,它利用fs.writeFile 上的util.promisify 等待每次写入,然后再进行下一次写入,接收要写入的文件数组data
    • minify 是一个异步函数,可以缩小 JS

    这将给出您想要的readAllwriteAllminify 的顺序

    正如它所写,它正在尝试执行以下操作

    • 读取文件
    • 写那个文件
    • 对所有文件重复
    • 然后缩小

    由于您正在学习,提供的链接应该给出如何编写异步函数的回调、基于 promise 和 async-await 的示例。

    【讨论】:

    • 谢谢@Manny。我实际上是在谈论npmjs.com/package/async 包。无论如何,我用他们的sync 函数替换了readFilewriteFile,它按预期工作。这些函数异步工作,不需要一个 promise 回调。
    猜你喜欢
    • 1970-01-01
    • 2017-07-21
    • 1970-01-01
    • 1970-01-01
    • 2010-12-02
    • 1970-01-01
    • 1970-01-01
    • 2015-09-08
    • 1970-01-01
    相关资源
    最近更新 更多