我正在创建一个Express服务器,允许客户端从不同的来源接收下载的文件。
下载的文件之一是zip文件,需要在将其发送到客户端之前将其解压缩。暴露给节点客户端的API具有Promise.all(),以确保在下载和提取所有内容之前不会发回文件。
// Client would call this as /download API. Once the download is completed (along with zip extraction), these files would be send to client
function download() {
return Promise.all([downloadInvoice(), downloadImages()]);
})
}).then(function (result) {
// this is happening even before the zip is extracted
console.log('content downloaded and zip extracted, send everything to client');
})
})
}
downloadImages函数调用REST服务(POST)来获取图像,然后使用管道将图像写入文件系统。将zip保存在文件系统中后,我使用提取模块将zip解压缩到一个文件夹。
var req = require('request');
var extract = require('extract-zip')
function downloadImages() {
return new Promise(function(resolve, reject) {
var imageUrl = 'http://localhost:8080/restserver/downloadImages';
var postData = {
username: 'abc',
password: 'xyz'
}
var options = {
method: 'post',
body: postData,
json: true,
url: imageUrl
}
req(options, function (err, res, body) {
if (err) {
console.log('Error posting json '+err)
return;
}
console.log('Status code '+res.statusCode);
}).pipe(fs.createWriteStream('C:/temp/Images.zip'))
.on('finish',function() { // 'finish' fired as download completed. Now extract
console.log('Finished downloading Images, now extract them');
extract('C:/temp/Images.zip',
{dir: 'C:/temp/Images'},
function (err) {
if(err) {
console.log('Error extracting Images zip '+err);
}
resolve("Promised resolved for Images");
})
}).on('error', function(error) {
reject('Error extracting images', error);
});
}
}
我面临的挑战是,即使在zip提取之前,Promise.all也会解决。因此,空文件夹将发送给客户端。
我希望事情按此顺序发生 - 1. Promise.all in download()用于实例化下载 2. DownloadImages()下载图像压缩并保存在节点服务器上(使用管道) 3. DownloadImages()提取zip 4. Promise.all in download()完成并将提取的图像发送给客户端。
第3步发生在第4步之后。我无法弄清楚我做错了什么来按正确的顺序链接这些操作。