stream.finished(stream[, options], callback)


  • stream <Stream> 可读和/或可写的流。
  • options <Object>
    • error <boolean> 如果设置为 false,则对 emit('error', err) 的调用不会被视为已完成。 默认值: true.
    • readable <boolean> 当设置为 false 时,即使流可能仍然可读,也会在流结束时调用回调。 默认值: true.
    • writable <boolean> 当设置为 false 时,即使流可能仍可写,也会在流结束时调用回调。 默认值: true.
  • callback <Function> 采用可选的错误参数的回调函数。
  • 返回: <Function> 清除所有已注册监听器的函数。

当流不再可读、可写或遇到错误或过早关闭事件时获得通知的函数。

const { finished } = require('stream');

const rs = fs.createReadStream('archive.tar');

finished(rs, (err) => {
  if (err) {
    console.error('Stream failed.', err);
  } else {
    console.log('Stream is done reading.');
  }
});

rs.resume(); // 排空流。

在流被过早销毁(如中止的 HTTP 请求)并且不会触发 'end''finish' 的错误处理场景中特别有用。

finished API 也是可 promise 化的;

const finished = util.promisify(stream.finished);

const rs = fs.createReadStream('archive.tar');

async function run() {
  await finished(rs);
  console.log('Stream is done reading.');
}

run().catch(console.error);
rs.resume(); // 排空流。

stream.finished() 在调用 callback 后离开悬空事件监听器(特别是 'error''end''finish''close')。 这样做的原因是意外的 'error' 事件(由于不正确的流实现)不会导致意外崩溃。 如果这是不需要的行为,则需要在回调中调用返回的清理函数:

const cleanup = finished(rs, (err) => {
  cleanup();
  // ...
});
  • stream <Stream> A readable and/or writable stream.
  • options <Object>
    • error <boolean> If set to false, then a call to emit('error', err) is not treated as finished. Default: true.
    • readable <boolean> When set to false, the callback will be called when the stream ends even though the stream might still be readable. Default: true.
    • writable <boolean> When set to false, the callback will be called when the stream ends even though the stream might still be writable. Default: true.
  • callback <Function> A callback function that takes an optional error argument.
  • Returns: <Function> A cleanup function which removes all registered listeners.

A function to get notified when a stream is no longer readable, writable or has experienced an error or a premature close event.

const { finished } = require('stream');

const rs = fs.createReadStream('archive.tar');

finished(rs, (err) => {
  if (err) {
    console.error('Stream failed.', err);
  } else {
    console.log('Stream is done reading.');
  }
});

rs.resume(); // Drain the stream.

Especially useful in error handling scenarios where a stream is destroyed prematurely (like an aborted HTTP request), and will not emit 'end' or 'finish'.

The finished API is promisify-able as well;

const finished = util.promisify(stream.finished);

const rs = fs.createReadStream('archive.tar');

async function run() {
  await finished(rs);
  console.log('Stream is done reading.');
}

run().catch(console.error);
rs.resume(); // Drain the stream.

stream.finished() leaves dangling event listeners (in particular 'error', 'end', 'finish' and 'close') after callback has been invoked. The reason for this is so that unexpected 'error' events (due to incorrect stream implementations) do not cause unexpected crashes. If this is unwanted behavior then the returned cleanup function needs to be invoked in the callback:

const cleanup = finished(rs, (err) => {
  cleanup();
  // ...
});