Проблемы с вложенными асинхронными функциями (асинхронный водопад в асинхронных рядах) - PullRequest
0 голосов
/ 18 мая 2018

Пожалуйста, помогите с этим, я новичок с nodejs, и это распространенная проблема, и я попробовал примеры в постах других здесь.У меня проблема, когда в последней функции.

Я пытаюсь:

  1. Проверьте, существует ли data.json и создайте его с некоторыми данными с async.waterfall

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);
}
Чтение data.json, получение данных, добавление некоторой информации и сохранение data.json с помощью async.waterfall

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);
}
Присоединяйтесь к функциям с помощью async.series

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 голосов
/ 18 мая 2018

Поскольку @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));
0 голосов
/ 18 мая 2018

Я не уверен в точной проблеме, с которой вы столкнулись, но я вижу проблему в вашем коде.callback в обеих функциях IfDataDontExistsCreate и AppendtoDataFile вызывается до завершения выполнения асинхронного водопада.

Вызов callback(err, null) из финального обратного вызова async.waterfall и удаление последней строки, т.е. callback(null, callback) из обеих функций, должны решить проблему для вас.

...