【发布时间】:2020-02-17 20:24:13
【问题描述】:
我有兴趣了解如何 Promisfy 这段代码:
const http = require('http');
const fs = require('fs');
const download = function(url, dest, cb) {
let file = fs.createWriteStream(dest);
const request = http.get(url, function(response) {
response.pipe(file);
file.on('finish', function() {
file.close(cb); // close() is async, call cb after close completes.
});
}).on('error', function(err) { // Handle errors
fs.unlink(dest); // Delete the file async. (But we don't check the result)
if (cb) cb(err.message);
});
};
我对此的第一个看法是:
const http = require('http');
const fs = require('fs');
const download = async (url, dest, cb) => {
let file = fs.createWriteStream(dest);
const request = http.get(url, function(response) {
response.pipe(file);
file.on('finish', function() {
const closed = await file.close(cb); // close() is async, await here?
if (closed) {
// handle cleanup and retval
}
});
}).on('error', function(err) { // Handle errors
const deleted = await fs.unlink(dest); // Delete the file async.
if (!deleted) { ... }
});
};
上面的实现显然是错误的。什么是正确的方法来删除回调并只使用 async/await?
【问题讨论】:
-
两个提示。首先,在最新版本的 node.js 中,使用
fs.promises接口到fs模块。这就是您获得对fs模块的承诺支持的地方。像fs.unlink()这样的常规函数根本不支持 Promise,因此将await与它们一起使用没有任何用处。其次,流媒体没有内置的 Promise 支持。如果您想承诺使用流媒体的东西,您必须手动将其放入new Promise(...)并在流媒体完成或出现错误时手动调用resolve()和reject()。 -
@jfriend00
streaming has no built-in promise support-- 不完全正确,请参阅可读流接口上的Symbol.asyncIterator。 -
@PatrickRoberts - 好吧,我猜这很新(至少对我来说是新的)。您能否发布一个最能说明如何在这种情况下使用它的答案?
-
&jfriend00 我可以,但现在不行。如果你想对我进行 FGITW,我不会被冒犯
-
@PatrickRoberts - 老实说,我还没有深入了解 asyncIterators 或了解您如何使用它们来知道
.pipe()何时完成,这是我认为需要知道的。
标签: javascript node.js promise async-await