[javascript] Node.js وضع نفس التدفق المقارن في عدة أهداف (قابلة للكتابة)



1 Answers

لا تعمل الإجابة الأولى إلا إذا كانت التدفقات تستغرق تقريبًا نفس مقدار الوقت اللازم لمعالجة البيانات. إذا استغرق المرء وقتًا أطول بشكلٍ كبير ، فستتطلب أسرع أكثر البيانات الجديدة ، مما يؤدي إلى استبدال البيانات التي لا تزال تستخدمها البيانات الأبطأ (واجهت هذه المشكلة بعد محاولة حلها باستخدام دفق مكرر).

النمط التالي يعمل بشكل جيد للغاية بالنسبة لي. ويستخدم مكتبة تعتمد على Stream2 تدفقات ، Streamz ، ووعود لمزامنة تيارات async عبر رد اتصال. باستخدام المثال المألوف من الإجابة الأولى:

spawn = require('child_process').spawn;
pass = require('stream').PassThrough;
streamz = require('streamz').PassThrough;
var Promise = require('bluebird');

a = spawn('echo', ['hi user']);
b = new pass;
c = new pass;   

a.stdout.pipe(streamz(combineStreamOperations)); 

function combineStreamOperations(data, next){
  Promise.join(b, c, function(b, c){ //perform n operations on the same data
  next(); //request more
}

count = 0;
b.on('data', function(chunk) { count += chunk.length; });
b.on('end', function() { console.log(count); c.pipe(process.stdout); });
Question

أحتاج إلى تشغيل أمرين في سلسلة تحتاج إلى قراءة البيانات من نفس الدفق. بعد توجيه تيار إلى آخر ، يتم إفراغ المخزن المؤقت لذلك لا يمكنني قراءة البيانات من ذلك الدفق مرة أخرى حتى لا ينجح ذلك:

var spawn = require('child_process').spawn;
var fs = require('fs');
var request = require('request');

var inputStream = request('http://placehold.it/640x360');
var identify = spawn('identify',['-']);

inputStream.pipe(identify.stdin);

var chunks = [];
identify.stdout.on('data',function(chunk) {
  chunks.push(chunk);
});

identify.stdout.on('end',function() {
  var size = getSize(Buffer.concat(chunks)); //width
  var convert = spawn('convert',['-','-scale',size * 0.5,'png:-']);
  inputStream.pipe(convert.stdin);
  convert.stdout.pipe(fs.createWriteStream('half.png'));
});

function getSize(buffer){
  return parseInt(buffer.toString().split(' ')[2].split('x')[0]);
}

طلب يشكو من هذا

Error: You cannot pipe after data has been emitted from the response.

ويؤدي تغيير inputStream إلى fs.createWriteStream إلى إصدار نفس المشكلة بالطبع. لا أرغب في الكتابة في ملف ، ولكن أعِد استخدامها بطريقة ما التي ينتجها الطلب (أو أي شيء آخر لهذا الأمر).

هل هناك طريقة لإعادة استخدام دفق مقروء بمجرد الانتهاء من الأنابيب؟ ما هي أفضل طريقة لإنجاز شيء مثل المثال السابق؟




ماذا عن الأنابيب في اثنين أو أكثر من تيارات لا في نفس الوقت؟

فمثلا :

var PassThrough = require('stream').PassThrough;
var mybiraryStream = stream.start(); //never ending audio stream
var file1 = fs.createWriteStream('file1.wav',{encoding:'binary'})
var file2 = fs.createWriteStream('file2.wav',{encoding:'binary'})
var mypass = PassThrough
mybinaryStream.pipe(mypass)
mypass.pipe(file1)
setTimeout(function(){
   mypass.pipe(file2);
},2000)

لا ينتج عن الكود السابق أي أخطاء ولكن الملف file2 فارغ




Related