javascript - 一旦 json stringify writeStream 完成,如何解决 promise ?

标签 javascript node.js json stream

我使用 npm 的 big-json 来解决大型嵌套对象的 JSON.stringify() 限制。

一旦对象被字符串化,我就会将其保存到文件系统。

然而,这整个过程减慢了我的整体处理速度 - 我假设这与我现在可能正在等待流超时或关闭之前的某些情况有关。

这是我的代码:

const fs = require('fs-extra');
const json = require('big-json');

function offlineSave(objArr){
  return new Promise((resolve, reject) => {
    let promises = [];
    for(let obj of objArr){
      const filePath = path.join(__dirname, `${obj}.json`);
      //this used to be a promisified fs.writeFile() - which seemed to be faster
      promises.push(saveStreamPromise(filePath,obj));
    }
    Promise.all(promises)
    .then((msg) =>{
      resolve(`Saved ${msg.length} files`);
    });
  });
}

let saveStreamPromise = function(filePath, obj){
  return new Promise((resolve, reject) =>{
    let stream = fs.createWriteStream(filePath, { flag: 'w+' });
    const stringifyStream = json.createStringifyStream({ body: obj});
    stringifyStream.on('data', strChunk =>{
      stream.write(strChunk);
    });

    //is this the correct way to return a promise upon stringify complete?
    stringifyStream.on('end', () =>{
      stream.end();
      resolve(`${obj} saved!`);
    });
  });
}

最佳答案

您的代码正在监听读取流的结尾。虽然这可能有效,但最好监听写入流的末尾,这样您只有在数据提交到磁盘后才解决 promise 。

最好将两个流的错误处理添加到任一流拒绝 promise 的任何错误中:

function saveStreamPromise(filePath, obj){
  return new Promise((resolve, reject) =>{
    let stream = fs.createWriteStream(filePath, { flag: 'w+' });
    const stringifyStream = json.createStringifyStream({ body: obj});
    stringifyStream.on('data', strChunk =>{
      stream.write(strChunk);
    });

    // resolve when read stream and write stream are done
    stringifyStream.on('end', () =>{
      stream.end(function() {
          resolve('object saved!');
      });
    }).on('error', reject);
    stream.on('error', reject);
  });
}

我还建议您使用 .pipe() 自动将一个流提供给另一个流,如下所示:

function saveStreamPromise(filePath, obj){
  return new Promise((resolve, reject) =>{
    let stream = fs.createWriteStream(filePath, { flag: 'w+' });
    const stringifyStream = json.createStringifyStream({ body: obj});
    stringifyStream.pipe(stream);

    // when using pipe, the write stream will automatically close when the
    // readable gets to the end of its data

    stream.on('error', reject).on('close', function() {
        resolve('object saved!');
    });
    stringifyStream.on('error', reject);
}

并且,${obj}已保存!只会给您类似“[object object]已保存!”的信息这可能不是您想要的。

关于javascript - 一旦 json stringify writeStream 完成,如何解决 promise ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57863342/

相关文章:

javascript - 在 JavaScript 中获取客户端的时区(和偏移量)

node.js - Elastic Beanstalk 上传和部署错误 : Error: Cannot find module 'semver'

node.js - 断开连接后 Socket.io 套接字数据可用性

javascript - 在 JavaScript 中只有特定的 JSON 属性

javascript - 可以转换 .vtk 吗?

javascript - Angularjs 获取 json 在谷歌地图中不起作用

javascript - Angular 2 如何在按钮返回时模糊输入?

javascript - Array.prototype.sort(compareFn) 在浏览器中的工作方式不同?

javascript - <button formtarget ="_blank"></button> 不起作用

node.js - Nodejs Harmony/ES6 中的 map 集合损坏了?