Node.js - Gunzip已读文件异步问题
相对较新的node.js和异步处理方式,到目前为止我已经能够使用promise读取使用fs readFile的文件,但我没有'没有任何运气让zlib Gunzip工作。写作的CoffeeScript:Node.js - Gunzip已读文件异步问题
promisifyRun(fs, 'readFile', filepath, 'utf-8')
.then (file) ->
promisifyRun(zlib, 'Gunzip', file)
.then (data) ->
console.log "HELLO"
return data
.catch respondError res
promisfyRun是有前途的一个单一的功能(我没有写出来,但它的工作)。我已经设法成功地使用它的fs.readFile组件,就像这样:
promisifyRun(fs, 'readFile', filepath, 'utf-8')
.then (data) ->
return data
.catch respondError res
这只是正常,等待要打开的文件,然后继续。 'data'包含文件的主体。我认为它应该是一个非常合理的扩展,以纳入gunzip组件,但到目前为止这一直是一个挑战。
我看了几个npm gunzip模块。似乎最有趣的那个是gunzip-maybe或zlib.Gunzip(我在这里尝试)。
对于这种特殊情况下的错误消息已:
"Unhandled rejection Error: Can't set headers after they are sent."
我认为这是相关的过程中就已经有其异步的完成事业
更新 - 全堆栈跟踪:
Unhandled rejection Error: Can't set headers after they are sent. at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:357:11) at ServerResponse.header (/Users/jcook/project/node_modules/express/lib/response.js:725:10) at ServerResponse.send (/Users/jcook/project/node_modules/express/lib/response.js:170:12) at ServerResponse.json (/Users/jcook/project/node_modules/express/lib/response.js:256:15) at ServerResponse.send (/Users/jcook/project/node_modules/express/lib/response.js:158:21) at /Users/jcook/project/.tmp/lib/util.js:40:22 at tryCatcher (/Users/jcook/project/node_modules/bluebird/js/release/util.js:16:23) at Promise._settlePromiseFromHandler (/Users/jcook/project/node_modules/bluebird/js/release/promise.js:512:31) at Promise._settlePromise (/Users/jcook/project/node_modules/bluebird/js/release/promise.js:569:18) at Promise._settlePromise0 (/Users/jcook/project/node_modules/bluebird/js/release/promise.js:614:10) at Promise._settlePromises (/Users/jcook/project/node_modules/bluebird/js/release/promise.js:689:18) at Async._drainQueue (/Users/jcook/project/node_modules/bluebird/js/release/async.js:133:16) at Async._drainQueues (/Users/jcook/project/node_modules/bluebird/js/release/async.js:143:10) at Immediate.Async.drainQueues (/Users/jcook/project/node_modules/bluebird/js/release/async.js:17:14) at runCallback (timers.js:672:20) at tryOnImmediate (timers.js:645:5) at processImmediate [as _immediateCallback] (timers.js:617:5)
当你看到Can't set headers after they're sent
,它几乎始终是因为您的请求处理程序在端点响应后仍在执行,其中的IME与不等待回调完成的代码有99%的关联。
首先,您不否认承诺的使用承诺的许多好处。
promisifyRun(fs, 'readFile', filepath, 'utf-8')
.then (file) ->
// Just return another promise here.
return promisifyRun(zlib, 'Gunzip', file)
.then (data) ->
console.log "HELLO"
return data
.catch respondError res
其次,您从回调中运行return data
。我的猜测是,你正试图在另一侧用一个返回值,像这样:
run =()->
promisifyRun(fs, 'readFile', filepath, 'utf-8')
.then (file) ->
// Just return another promise here.
return promisifyRun(zlib, 'Gunzip', file)
.then (data) ->
console.log "HELLO"
return data
.catch respondError res
myData = run()
这不起作用,因为什么东西被从承诺返回是异步的。您需要处理响应异步:
run =()->
promisifyRun(fs, 'readFile', filepath, 'utf-8')
.then (file) ->
// Just return another promise here.
return promisifyRun(zlib, 'Gunzip', file)
// We remove the rest of the function,
// so it just returns the promise above.
run().then (data)->
console.log data
一旦CS 2.0的土地,你就可以使用ES6异步/ AWAIT:
data = await run()
这太棒了!感谢这样一个彻底的答复,我刚刚了解到承诺,我认为这让我有点头脑围绕他们的预期效用。 – cookersjs
一个简单而有效的方法是使用fs和zlib模块我节点:
fs.createReadStream('./file.gz')
.pipe(zlib.createGunzip())
.pipe(res);
如果你的情况,你有文件内容只有缓冲区,然后zlib.gunzip
足够:
zlib.gunzip(buffer, (err, gunzippedBuffer) => {
// ...
});
见https://nodejs.org/dist/latest-v6.x/docs/api/zlib.html#zlib_zlib_gunzip_buf_options_callback
我试过了第一个选项,但是我收到一条消息说'TypeError:fs.createReadStream(...)。pipe不是函数' – cookersjs
什么是完整的堆栈跟踪? – LEQADA
请发送发送标题的代码。你的'util。tryCatcher'(或使用它的代码)可能是问题。 – Bergi