我正试图了解承诺,我想我可以看到它们的工作方式,你可以说Step 1
,Step 2
然后Step 3
。
我使用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)
});
}
所以这一切都按顺序执行,我可以看到它是如何工作的。
我有另一种方法,然后将CSV文件转换为JSON(再次使用保证)
## 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
}
当我一个接一个地调用这些函数时,第二个函数失败,因为第一个函数没有完成。
我是否需要将这两个函数调用包含在另一个承诺中,即使它们各自都已实现了承诺?
请告知我是否完全误解了这个
答案 0 :(得分:2)
当我一个接一个地调用这些函数时,第二个函数失败,因为第一个函数没有完成。
第一个有两个问题:
要处理第一个问题,您必须等待目标流上的finish
事件(pipe
返回)。为了处理第二个问题,你需要回复一个在这种情况发生之前不会实现的承诺。这些内容(见**
评论):
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
和catch
进行下一步:
theFunctionAbove("/some/url", "some-target")
.then(() = {
// It worked, do the next thing
})
.catch(err => {
// It failed
});
(或async
/ await
。)
旁注:我还没有对其进行代码审核,但csvToJson
中的一个严重问题跳了出来,这也是一个小问题,而@Bergi突出了第二个问题:
在{
逻辑
}
和else
小问题是您有var data = data.toString();
但data
是该函数的参数,因此var
具有误导性(但无害)
它没有正确处理else
回调的readFile
部分代码中的错误
我们可以通过在resolve
中执行else
并在then
处理程序中执行其余逻辑来解决这两个问题:
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;
});
}