【发布时间】:2016-08-07 07:38:09
【问题描述】:
我将文件存储在 Amazon S3 中,但也维护本地文件缓存。当我需要一个文件时,我想先检查缓存。我想避免在读取之前测试本地文件是否存在,因为 fs.exists 将被弃用,并且文件实际上可以在存在检查和文件读取之间被删除。
我想使用 Promise 和 Streams。下面的示例回退到另一个本地文件。我的真实代码将 S3 作为后备。
以下会是一个好的解决方案吗? 我发现获取失败读取信息的唯一方法是将错误处理程序连接到流。一旦我得到“可读”事件,我就会解开我的临时错误处理程序。
我也想知道当我使用“once”连接处理程序时是否真的需要解开处理程序。
'use strict';
const fs = require('fs');
function tryToReadLocalFile() {
return new Promise(function(resolve, reject) {
let rs = fs.createReadStream('./test1.txt');
let errorListener = function(err) {
reject(err);
};
rs.once('error', errorListener)
rs.on('readable', () => {
rs.removeListener('error', errorListener);
resolve(rs)
});
});
}
function tryToReadAnotherFile() {
return new Promise(function(resolve, reject) {
let rs = fs.createReadStream('./test2.txt');
let errorListener = function(err) {
reject(err);
};
rs.once('error', errorListener)
rs.on('readable', () => {
rs.removeListener('error', errorListener);
resolve(rs)
});
});
}
tryToReadLocalFile()
.catch(function(err) {
if(err.code === 'ENOENT') {
console.log('test1.txt not found. Fallback to test2.txt')
//Reading from another file as a test. Should read from S3 as fallback
return tryToReadAnotherFile();
} else {
return Promise.reject(err);
}
}).then(function(file) {
console.log('writing to test.txt');
let ws = fs.createWriteStream('./test.txt');
file.pipe(ws);
});
--------- 编辑 -->
我现在已经实现了上述更紧凑的版本。不过,我仍然会感谢您对此的任何意见。这是解决这个问题的好方法吗?
如您所见,我不再费心检查 ENOENT。无论错误是什么,我都想回退到 S3。
function getFileFromStorageP(options) {
return new Promise(function(resolve, reject) {
let rs = fs.createReadStream(path.join(env.fsp.cacheDir, options.fileId));
rs.once('error', (err) => {reject(err)});
rs.once('readable', () => {resolve(rs)});
}).catch(function(err) {
return srvS3.download({
fileId: options.fileId
});
});
}
【问题讨论】: