我有server-app
从客户端接收音频流。我正在尝试使用chai
/ chai-http
测试应用,但它给了我这个错误:
[错误:结束后写]
问题是什么?
代码:
var chai = require('chai');
var chaiHttp = require('chai-http');
var server = require('../server-app');
var should = chai.should();
var fs = require('fs');
chai.use(chaiHttp);
describe('server', function() {
it('should work..', function (done){
var req = chai.request(server).post('/speech');
fs.createReadStream('./test.wav').pipe(req);
req.end(function (err,res){
console.log(err);//outputs: [Error: write after end]
done();
});
});
});
答案 0 :(得分:5)
在流完成将数据推送到请求之前,您正在调用req.end
。
我会做以下事情:
var readstream = fs.createReadStream('./test.wav');
readstream.pipe(req);
readstream.on('close', someFunction);
readstream.on('end', someFunction);
并在流的关闭或结束事件中调用req.end
。在发出这些事件之前,您正在调用req.end。
答案 1 :(得分:3)
基本上JavaScript是异步的,流或套接字连接是同步的,一旦你创建了一个流,你必须等待流关闭才能发出另一个请求
在你的情况下,一旦你打开流
就会执行可以使其工作的三个选项
答案 2 :(得分:2)
当源流发出end()
事件时,默认情况下,在管道上调用'end'
时。因此,您无需亲自致电end()
。
保留目标流的'finish'
和'error'
事件,以控制完成工作的时间或发生错误的时间:
fs.createReadStream('./test.wav').pipe(req);
req.on('error', (err) => {console.log(err);});
req.on('finish',() => {done();});
如果您想让作家(req
)保持打开状态,可以在管道时将end option
设置为false:
fs.createReadStream('./test.wav').pipe(req, options = {end = false});
但请记住,“完成”事件不会被管道触发。