节点 - 在Async函数中附加文件

时间:2018-03-12 14:40:13

标签: javascript node.js mongoose

我正在使用mongoose来查询数据库中的对象,并希望将每个对象写入文件。 console.log向我显示我想要的数据是从查询中返回的,但fs.append(./returned.json)创建的文件始终为空。是不是可以在异步函数中执行此操作?

async function findReturned(){
    try {
        const returned = await Data.find({});
        returned.forEach(function(file) {
            returnedfiles = file.BACSDocument;
            console.log(returnedfiles);
            fs.appendFile('./returned.json', returnedfiles, 'utf-8', (err) => {
                if (err) throw err;
            });
        });
        process.exit();
    } catch(e) {
        console.log('Oops...');
        console.error(e);
        process.exit();
    }
};

2 个答案:

答案 0 :(得分:0)

您不能将async函数和函数与回调API混合使用 此外,您无法在async内调用乘法forEach函数,您必须创建一个将在链中执行所需操作的承诺(请参阅下面的示例中的reduce函数)。

另一种方法 - 使用.map,返回一组promises并使用

等待它
await Proimse.all(arrayOfPromises)

但在这种情况下,文件中新数据的顺序不会与初始数组中的顺序相同。

为了做到这一点,你需要宣传fs.appendFile并调用promisified版本的函数

// add new import
const {promisify} = require('util');
// create new function with Promise API on existing Callback API function
const appendFile = promisify(fs.appendFile)

async function findReturned(){
    try {
    const returned = await Data.find({});

    // Create a single promise that will append each record one by one to the file in initial order.
    const promise = returned.reduce(function(acc, file){
        returnedfiles = file.BACSDocument;
        console.log(returnedfiles);
        acc.then(() => appendFile('./returned.json', returnedfiles, 'utf-8'));
        return acc
    }, Promise.resolve());

    // Wait until the promise resolves;
    await promise;

    process.exit();
    } catch(e) {
        console.log('Oops...');
        console.error(e);
        process.exit();
    }
};

您可以使用fs-extra模块,而不是使用build int fs模块,该模块已经具有本机方法的默认版本和一些额外的方法。

您可以在函数中改进的内容 - 不要追加文件乘法次数,而是将需要附加到文件中的所有数据收集到单个变量中并执行一次。

如果由于某种原因你需要多次执行 - 使用fs.open获取文件描述符并将其传递给fs.appendFile(或promisified verison)而不是文件名。在这种情况下,请不要忘记co close文件描述符(fs.Close)。

答案 1 :(得分:0)

您可能应该将mz / fs用于异步功能

const fs = require('mz/fs');

...
returned.forEach(async (file) => {
   returnedfiles = file.BACSDocument;
   await fs.writeFile('./returned.json', returnfiles, 'utf-8');
})

你不需要像捕捉那样抛出错误。