[英]Chaining methods using promises
I'm trying to get my head around promises, I think I can see how they work in the way that you can say do Step 1
, Step 2
and then Step 3
for example. 我正在努力兑现承诺,我想我可以看到它们的工作方式,例如您可以说先执行
Step 1
, Step 2
然后再执行Step 3
。
I have created this download function using node-fetch
(which uses native Promises) 我已经使用
node-fetch
(使用本机Promises)创建了此下载功能
## FileDownload.js
const fetch = require('node-fetch');
const fs = require('fs');
module.exports = function(url, target) {
fetch(url)
.then(function(res) {
var dest = fs.createWriteStream(target);
res.body.pipe(dest);
}).then(function(){
console.log(`File saved at ${target}`)
}).catch(function(err){
console.log(err)
});
}
So this all executes in order and I can see how that works. 所以这一切按顺序执行,我可以看到它是如何工作的。
I have another method that then converts a CSV file to JSON (again using a promise) 我有另一种方法,然后将CSV文件转换为JSON(再次使用Promise)
## CSVToJson.js
const csvjson = require('csvjson');
const fs = require('fs');
const write_file = require('../helpers/WriteToFile');
function csvToJson(csv_file, json_path) {
return new Promise(function(resolve, reject) {
fs.readFile(csv_file, function(err, data){
if (err)
reject(err);
else
var data = data.toString();
var options = {
delimiter : ',',
quote : '"'
};
const json_data = csvjson.toObject(data, options);
write_file(json_path, json_data)
resolve(data);
});
});
}
module.exports = {
csvToJson: csvToJson
}
When I call these functions one after another the second function fails as the first has not completed. 当我一个接一个地调用这些功能时,第二个功能失败,因为第一个功能尚未完成。
Do I need to wrap these two function calls inside another promise, even though on their own they each have promises implemented? 我是否需要将这两个函数调用包装在另一个promise中,即使它们各自实现了promise?
Please advise if I am totally misunderstanding this 请告知我是否完全误解了
When I call these functions one after another the second function fails as the first has not completed.
当我一个接一个地调用这些功能时,第二个功能失败,因为第一个功能尚未完成。
There are two issues with the first: 第一个有两个问题:
To deal with the first issue, you have to wait for the finish
event on the destination stream (which pipe
returns). 要处理第一个问题,您必须等待目标流(
pipe
返回)上的finish
事件。 To deal with the second, you need to return a promise that won't be fulfilled until that happens. 要处理第二个问题,您需要返回一个承诺,直到这种情况发生,该承诺才能兑现。 Something along these lines (see
**
comments): 遵循以下原则(请参见
**
评论):
module.exports = function(url, target) {
// ** Return the end of the chain
return fetch(url)
.then(function(res) {
// ** Unfortunately, `pipe` is not Promise-enabled, so we have to resort
// to creating a promise here
return new Promise((resolve, reject) => {
var dest = fs.createWriteStream(target);
res.body.pipe(dest)
.on('finish', () => resolve()) // ** Resolve on success
.on('error', reject); // ** Reject on error
});
}).then(result => {
console.log(`File saved at ${target}`);
return result;
});
// ** Don't `catch` here, let the caller handle it
}
Then you can use then
and catch
on the result to proceeed to the next step: 然后,您可以使用
then
并catch
结果以继续进行下一步:
theFunctionAbove("/some/url", "some-target")
.then(() = {
// It worked, do the next thing
})
.catch(err => {
// It failed
});
(Or async
/ await
.) (或
async
/ await
。)
Side note: I haven't code-reviewed it, but a serious issue in csvToJson
jumped out, a minor issue as well, and @Bergi has highlighted a second one: 旁注:我尚未对其进行代码审查,但
csvToJson
一个严重问题跳了出来,也是一个小问题,@ Bergi突出了第二个问题:
It's missing {
and }
around the else
logic else
逻辑中缺少{
和}
The minor issue is that you have var data = data.toString();
小问题是您有
var data = data.toString();
but data
was a parameter of that function, so the var
is misleading (but harmless) 但是
data
是该函数的参数,因此var
具有误导性(但无害)
It doesn't properly handle errors in the part of the code in the else
part of the readFile
callback 它无法正确处理
readFile
回调的else
部分中的部分代码错误
We can fix both by doing a resolve
in the else
and performing the rest of the logic in a then
handler: 我们可以通过在
else
进行resolve
并在then
处理程序中执行其余逻辑来解决这两个resolve
:
function csvToJson(csv_file, json_path) {
return new Promise(function(resolve, reject) {
fs.readFile(csv_file, function(err, data){
if (err)
reject(err);
else
resolve(data);
});
})
.then(data => {
data = data.toString();
var options = {
delimiter : ',',
quote : '"'
};
const json_data = csvjson.toObject(data, options);
write_file(json_path, json_data);
return data;
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.