代码之家  ›  专栏  ›  技术社区  ›  AndresSp

嵌套异步函数的问题(异步系列中的异步瀑布)

  •  0
  • AndresSp  · 技术社区  · 7 年前

    请提供一些帮助,我是nodejs新手,这是一个常见的问题,我在其他帖子中尝试了这些例子。我在上一个函数中遇到问题。

    我正在尝试:

    1. 检查是否存在数据。json存在,并使用一些异步数据创建它。瀑布

    function IfDataDontExistsCreate(callback)
    {
        async.waterfall([ //If data dont exists
            function IfExistDataFile(callback) {
                fs.exists(path, function(exists){
                    if(!exists)
                    {
                        try {
                            const firstDataFile = {"readedPosts":{"id": []}};
                            const json = JSON.stringify(firstDataFile, null, 2);
                            callback(null, json);
                        } catch (error) {
                            callback(error);
                        }
                        
                    }
                }
            )},
            function CreateDataFile(json ,callback) {
                fs.writeFile(path, json, function (err) {
                    if(err) callback(err);
                })
            }
        ], function (err, callback) {
            if(err) throw err;
        });
    
        callback(null, callback);
    }
    1. 读取数据。json、获取数据、添加一些信息和保存数据。json与异步。瀑布

    function AppendtoDataFile(info, callback)
    {
        async.waterfall([
            function ReadGetData(callback) {
                fs.readFile(path, (err, data) => {
                    if(err) throw err;
                    let datajson = JSON.parse(data.toString());
                    datajson.readedPosts.id.push(info.toString()); //Add info
                    callback(err, datajson)
                })
            },
            function WriteDataFile(data, callback) {
                const writeData = fs.writeFile(path, JSON.stringify(data, null, 2), function (err) {
                    if(err) throw err;
                    callback(err);
                })
            }
        ], function(err, callback)
        {
            if(err) throw err;
        });
    
        callback(null, callback);
    }
    1. 使用async连接函数。系列

    function AddPostID(postID, callback)
    {
        async.series({
            one: function (callback) {
                IfDataDontExistsCreate(function () {
                    callback(null, "DataFile Created");
                });
            },
            two: function (callback) {
                AppendtoDataFile(postID, function () {
                    callback(null, "PostID added to Datafile");
                });
            }
        }),
        function (err, results) {
            if(error) throw err;
            console.log(results);
        }
    }
    2 回复  |  直到 7 年前
        1
  •  3
  •   Marcos Casagrande    7 年前

    由于@Raeesaa已经回答了您的具体问题, 我用承诺和 async/await ,使代码更具可读性;清洁的

    首先,你可以避免 fs.exists 使用 fs.writeFile 具有 wx 标志:

    “wx”-与“w”类似,但如果路径存在,则会失败。


    'use strict';
    
    const fs = require('fs');
    const { promisify } = require('util');
    
    const writeFile = promisify(fs.writeFile);
    const readFile = promisify(fs.readFile);
    
    const path = '/tmp/foo.json';
    
    async function IfDataDontExistsCreate() {
        const firstDataFile = {
            readedPosts: {
                id: []
            }
        };
    
        const json = JSON.stringify(firstDataFile, null, 2);
    
        try {
    
            await writeFile(path, json, { flag: 'wx' });
        } catch(e) {
            // If EEXIST means the file is already created, do nothing
            if(e.code !== 'EEXIST')
                throw e;
        }
    }
    
    async function AppendtoDataFile(info) {
    
        const data = await readFile(path, 'utf8');
    
        let datajson = JSON.parse(data);
        datajson.readedPosts.id.push(info.toString()); // Add info
    
        return writeFile(path, JSON.stringify(datajson, null, 2));
    }
    
    async function AddPostID(postID) {
    
        // Wait until the file is created
        await IfDataDontExistsCreate();
        console.log('DataFile Created');
    
        // We append after the file has been created
        await AppendtoDataFile(postID);
        console.log('PostID added to Datafile');
    
        return true;
    }
    
    AddPostID(5)
      .then(res => console.log('Done!'))
      .catch(err => console.error(err));
    
        2
  •  2
  •   Raeesaa    7 年前

    我不确定您所面临的确切问题,但我确实在您的代码中看到了一个问题。这个 callback 在两种功能中 IfDataDontExistsCreate AppendtoDataFile 在异步瀑布完成执行之前调用。

    使命感 callback(err, null) 来自异步的最终回调。瀑布和移除最后一行,即。 callback(null, callback) 从这两个函数可以为您解决问题。