当前位置: 首页 > 知识库问答 >
问题:

可以对流进行回调。写操作是否可靠?是否验证写操作是否成功?

呼延光明
2023-03-14

我正在编写一个带有事务回滚的简单json数据库。我需要向一个文件追加一行文本,然后根据追加是否成功,将成功或失败记录到另一个文件。如果需要,第二个文件用于回滚。因此,在继续之前,我需要确定写操作是否成功。

我使用stream.write追加我的文本行,其中包括一个回调,应该验证写操作的成功或失败。

然后我在下面的URL上的NodeJS文档中读到了这个不幸的消息https://nodejs.org/api/stream.html#stream_class_stream_writable

可写的。write()方法将一些数据写入流,并在完全处理数据后调用提供的回调。如果发生错误,可以调用回调,也可以不调用回调,并将错误作为其第一个参数。要可靠地检测写入错误,请为“错误”事件添加侦听器。

因此,尽管下面的代码似乎有效,但文档称它不可靠。

  // Wait till the file is open before trying to write to it.
  wStream.on('open', function() 
  {
    // Call function to append the string to the file with a new line character added at the end.
    wStream.write(stringData + '\n', function(error)
    {
      if(!error) // If the string was appended successfully:
      {
        callback(false); // Report back there was no error
      }
      else // The string was not appended successfully.
      {
        lib.log
        (
          'h0fceuftq8xkdkvh4dl9' + '\n' +
          'Error appending to file ' + fileName + '\n' +
          'This was the error:' + '\n' +
          JSON.stringify(error) + '\n' + 
          '\n'
        );

        callback('Error appending to file ' + fileName)
      } // End of: else The string was not appended successfully.

    }); //End of: wStream.write(...
    // End of: Call function to append the string to the file with a new line character added at the end.   

  }); // End of: wStream.on('open', function(){Do stuff}
  // End of: Wait till the file is open before trying to write to it.

文档说要添加这样的侦听器,但我的问题是它不是回调的一部分

  // Listen for errors on the write stream and log them.
  wStream.on('error', function(error)
  {
    lib.log
    (
      'pmazz7shsko8mfnc0gyz' + '\n' +
      'An error occured when appending to ' + fileName + '\n' +
      'This was the error:' + '\n' +
      JSON.stringify(error) + '\n' +
      '\n'
    );
  }); // End of: wStream.on('error', function(error)
  // End of: Listen for errors on the write stream and log them. 

我还没有找到任何示例代码来说明如何做到这一点。所以我想我的问题是:我是否可以以某种方式将on-error侦听器写入回调,或者是否有其他方法来回调写入是否成功?

谢谢你,约翰

共有2个答案

芮歌者
2023-03-14

管道就是我要找的。

文件描述如下:

一种模块方法,用于在流之间通过管道转发错误并正确清理,并在管道完成时提供回调。

我的信息来源如下。源码

此外,Anto Aravine关于SkiShare的名为“通过示例理解NodeJS流”的课程非常有帮助。

下面是将json记录追加到文件的完成函数,它提供了一种可靠的方法来回调追加的成功或失败。(实际上,无论追加操作期间是否存在错误)。

// Define function to append a string to a file  
// and create the file if it does not exist.  
lib.append = function(dir, fileName, appendObject, callback)
{
  // Convert the data object to a string.
  let stringData = JSON.stringify(appendObject);

  // Create a readable stream.
  const sourceStream = new Readable();

  // Load the readable stream with data.
  sourceStream.push(stringData + '\n');

  // Tell the stream no more data is coming.
  sourceStream.push(null);

  // Create a writable stream and specify the file which will receive the data from the readable stream.
  let destinationStream = fs.createWriteStream(lib.baseDir + dir + '/' + fileName + '.json', {flags : 'a'});


  pipeline
  (
    sourceStream,
    destinationStream,
    function(error)
    {
      if (!error) // If the string was appended successfully:
      {
        callback(false); // Report back there was no error
      } 
      else // The string was not appended successfully.
      {
        // Write the error to a log file
        lib.log
        (
          'h0fceuftq8xkdkvh4dl9' + '\n' +
          'Error appending to file ' + fileName + '\n' +
          'This was the error:' + '\n' +
          JSON.stringify(error) + '\n' + 
          '\n'
        );

        // This starts the rollback process for all files involved.
        callback
        (
          'h0fceuftq8xkdkvh4dl9' + '\n' +
          'Error appending to file ' + fileName + '\n' +
          'This was the error:' + '\n' +
          JSON.stringify(error) + '\n'
        );        
      }
    }
  );
}; // End of: lib.append = function(...
// End of: Append a string to a file. 
弓嘉纳
2023-03-14

我认为您不需要为每次写入提供回调。如果未执行error事件,则表示所有写入操作都成功

 writer.on('error', function(error){
    // handle all errors here
 });

您需要调用编写器。end('Last string to write')让流知道这是您的最后一次写入,然后将触发finish事件,这样您就可以说所有写入都完成了。

我希望这有帮助

 类似资料:
  • 问题内容: 我遇到了以下SYBASE SQL: 该SQL的结果是 这看起来像是将HAVING条件应用于行而不是组。有人可以帮我指出描述这种情况的地方是Sybase 15.5文档吗?我所看到的只是“在团队中运作”。我在文档中看到的最接近的是: hading子句可以包括不在选择列表中且不在group by子句中的列或表达式。 (从这里引用)。 但是,他们没有完全解释当您这样做时会发生什么。 问题答案:

  • 这是我的代码(简单但有效),它是一个计算引擎,通过按特定顺序应用规则进行试验: 我想用自定义注释对此进行编码,因为我的目标是统计哪些引擎调用哪些规则,我认为这会更容易: 然后我可以用org扫描。springframework。上下文注释。ClassPathScanningCandidateCom使统计更容易。 这可能吗(怎么可能?)?这是好办法吗?我还有别的办法吗?

  • 问题内容: 我想知道单个文件的写入是否原子完成,从而对同一文件的write(“ bla bla”)和随后的write(“ herp derp”)永远不会导致交织,例如“ bla herp bla derp ”。假设这些写操作发生在不同的进程或线程中,什么决定了哪个先完成? 另外,read()是否始终以完全完成的所有先前写入的状态返回反映文件的数据(无论该数据实际上是否已写入磁盘)?例如,在writ

  • AFAIK对流求和的唯一方法是: 这里的问题是,每次调用都会创建一个新的,而不是更改可变类型。 对于

  • 我想测试一个返回流的方法。 现在,我已经为当somecondition=true时的情况编写了以下测试

  • 我有一个类,它有一个包含来自类的对象。我在中有一个函数,叫做。每个都有一个名为的函数,该函数返回一个值。我能以某种方式使用流使函数的主体看起来像这样吗?