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

时间:2018-05-17 23:40:54

标签: javascript json node.js asynchronous async.js

请帮助一下这个,我是nodejs的新手,这是一个常见的问题,我在这里的其他帖子中试过这些例子。在最后一个函数中我有问题。

我在尝试:

  1. 检查data.json是否存在,并使用async.waterfall
  2. 创建一些数据

    
    
    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. 使用async.waterfall读取data.json,获取数据,添加一些信息并保存data.json
    2. 
      
      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.series加入函数
      2. 
        
        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 个答案:

答案 0 :(得分:3)

由于@Raeesaa已回答您的具体问题, 我提供了使用promises和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));

答案 1 :(得分:2)

我不确定您遇到的确切问题,但我确实在您的代码中发现了问题。在异步瀑布完成执行之前,正在调用函数callbackIfDataDontExistsCreate中的AppendtoDataFile

从async.waterfall的最终回调中调用callback(err, null)并从这两个函数中移除最后一行(即callback(null, callback))应该可以解决问题。