我创建了一个"小型"服务器,它应该使用NodeJs,并承诺从给定目录中复制和压缩给定类型的文件。它必须分开,每一个都有承诺——阅读文件并打包。首先,我创建了这些承诺来检查它们是否有效,它们确实有效:
function packFile(file){
var fileName = path.basename(file);
console.log(' (+) Add to the archive : ' + fileName + ' ['+file+']');
archive.append(fs.createReadStream(file), { name:fileName });
}
Q.nfcall(recursive, pathGiven, filterGiven)
.then(function(data) {
var chain = Q.when();
for(var i = 0; i < data.length; i++){
console.log(' > '+data[i]+' > adding to chain ...');
chain = chain.then(packFile.bind(this, data[i]));
}
chain.then(function() {
archive.finalize();
});
Ofc,我补充道,在之前提交的代码前面:
fs = require('fs');
archiver = require('archiver');
Q = require('q');
recursive = require('recursive-readdir');
path = require('path');
所有这些都已清点完毕,运行良好。"archive"在一开始也被正确地初始化。
既然一切都成功了,是时候使用服务器了:
//Lets require/import the HTTP module
var http = require('http');
//Lets define a port we want to listen to
const PORT=8080;
//Create a server
var server = http.createServer(handleRequest);
//Lets start our server
server.listen(PORT, function(){
console.log("Server listening on: http://localhost:%s", PORT);
});
函数"handleRequest"相当大,所以为了了解它的要点,我将把部分放在应该处理这些承诺的地方:
switch(request.url) {
case '/formhandler':
if (request.method == 'POST') {
// (...) Got my "Sour" (Path to source directory ) and "Mask"
// Here i tried to place that promise chain, but server just skipped it and continued
Q.nfcall(recursive, Sour, Mask)
.then(function(data) {
var chain = Q.when();
for(var i = 0; i < data.length; i++){
console.log(' > '+data[i]+' > adding to chain ...');
chain = chain.then(packFile.bind(this, data[i]));
}
chain.then(function() {
console.log("whole chain resolved");
console.log('FINISHING');
archive.finalize();
});
});
// (...) Finishing this request
}
break;
}
我所做的似乎都不起作用。只要我使用这些承诺(这样称呼它们或在某些函数中称呼它们)。我不知道为什么。
编辑1我所说的跳过的意思是,我在那个处理程序中的promise前后放置了2个console.log。我应该看看:
LOG1
TEXT_FROM_PROMISES //Something those promises send to console.log
LOG2
但只有:
LOG1
LOG2
服务器已准备好接收另一个请求。
编辑2一些人在评论中建议更改packFile,这样它就会返回promise,所以我做到了:
function packFile(file){
return new Promise(function(resolve,reject){
var fileName = path.basename(file);
console.log(' (+) Adding to the archive : ' + fileName + ' ['+file+']');
archive.append(fs.createReadStream(file), { name:fileName });
});
}
代码的其余部分保持不变。结果是-现在只执行这个链中的第一个(如果我在脚本中称它为"单独",没有服务器),它仍然无法在服务器上工作。
编辑3
我再次更改了"packFile":
function packFile(file){
return new Promise(function(resolve,reject){
var fileName = path.basename(file);
console.log(' (+) Adding to the archive : ' + fileName + ' ['+file+']');
archive.append(fs.createReadStream(file), { name:fileName });
resolve("Success!");
});
}
并不是整个链都能工作——对于没有服务器版本的情况,但服务器上仍然不会发生任何事情。
编辑4我更改了
Q.nfcall(recursive, pathGiven, filterGiven)
.then(function(data) {
var chain = Q.when();
for(var i = 0; i < data.length; i++){
console.log(' > '+data[i]+' > adding to chain ...');
chain = chain.then(packFile.bind(this, data[i]));
}
chain.then(function() {
console.log("whole chain resolved");
archive.finalize();
});
}, function(reason) {
console.log("ERROR:"+reason); // Error!
});
并在控制台中得到一些新错误:
ERROR:TypeError: ignores.map is not a function
编辑5我用来存档的代码,只是用来制作和打开.zip,用我的"packFile"将文件添加到
archive = archiver.create('zip', {});
var output = fs.createWriteStream('./output.zip');
archive.pipe(output);
编辑6由于似乎需要更多的代码,每当我收到正确的请求时,我都会在服务器上调用这个函数(->检查这篇文章的开头)
function handleWithPromises(pathGiven, filterGiven){
console.log(' > Promising ...');
archive = archiver.create('zip', {});
var output = fs.createWriteStream('./output.zip');
archive.pipe(output);
function packFile(file){
return new Promise(function(resolve,reject){
var fileName = path.basename(file);
console.log(' (+) Adding to the archive : ' + fileName + ' ['+file+']');
archive.append(fs.createReadStream(file), { name:fileName });
resolve("Success!");
});
}
Q.nfcall(recursive, pathGiven, filterGiven)
.then(function(data) {
var chain = Q.when();
for(var i = 0; i < data.length; i++){
console.log(' > '+data[i]+' > adding to chain ...');
chain = chain.then(packFile.bind(this, data[i]));
}
chain.then(function() {
console.log('FINISHING');
archive.finalize();
});
});
}
和放在脚本的乞讨处的代码:
fs = require('fs');
archiver = require('archiver');
Q = require('q');
recursive = require('recursive-readdir');
path = require('path');
返回到您期望看到的编辑1
LOG1
TEXT_FROM_PROMISES //Something those promises send to console.log
LOG2
但得到
LOG1
LOG2
一种解释是,在调用then
的线程执行完成后,A+兼容承诺与事件循环调度程序的接口在其自己的线程中执行then
提供的函数。
Chained promise与定义它们的代码异步执行
在一个非常简单的层面上,您需要推迟结束请求,直到所有文件都打包好,方法是确保response
在最后一个匿名函数的函数范围内,并在那里结束响应:
chain.then(function() {
console.log('FINISHING');
archive.finalize();
response.write(...) // are you sending the archive back?
response.end(); // now end the request
});