【发布时间】:2016-06-10 14:18:01
【问题描述】:
我是 Promise 的新手,我确信那里有一个答案/模式,但我只是找不到一个对我来说足够明显的答案/模式是正确的。我正在使用 node.js v4.2.4 和 https://www.promisejs.org/
我认为这应该很容易...我需要按特定顺序执行多个异步块,其中一个中间块将循环通过一组 HTTP GET。
//New Promise = asyncblock1 - FTP List,解析返回的list数组 //.then(asynchblock2(list)) - 遍历列表数组和 HTTP GET 需要的文件 //.then(asynchblock3(list)) - 更新本地日志
我尝试创建一个新的 Promise,解决它,将列表传递给 .then,执行 GET 循环,然后更新文件。我尝试在 asynchblock2 中使用嵌套的 promise.all,但由于这些事件的时间安排,它实际上以相反的顺序进行,3、2 和 1。感谢您的帮助。
编辑:好的,这是我正在使用的有效模式,我现在只需要在中间有一个 GET 循环。
var p = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('2 sec');
resolve(1);
},
2000);
}).then(() => {
return new Promise((resolve) => {
setTimeout(() => {
console.log('1.5 sec');
// instead of this section, here I'd like to do something like:
// for(var i = 0; i < dynamicarray.length; i++){
// globalvar[i] = ftpclient.getfile(dynamicarray[i])
// }
// after this loop is done, resolve
resolve(1);
},
1500);
});
}).then(() => {
return new Promise((resolve) => {
setTimeout(() => {
console.log('1 sec');
resolve(1);
},
1000);
});
});
编辑这是几乎可以工作的代码!
var pORecAlert = (function(){
var pa;
var newans = [];
var anstodownload = [];
var anfound = false;//anfound in log file
var nexttab;
var lastchar;
var po;
var fnar = [];
var antext = '';
//-->> This section works fine; it's just creating a JSON object from a local file
try{
console.log('trying');
porfile = fs.readFileSync('an_record_files.json', 'utf8');
if(porfile == null || porfile == ''){
console.log('No data in log file - uploaded_files_data.json being initialized!');
plogObj = [];
}
else{
plogObj = JSON.parse(porfile);
}
}
catch(jpfp){
console.log('Error parsing log file for PO Receiving Alert: ' + jpfp);
return endPORecAlertProgram();
};
if((typeof plogObj) === 'object'){
console.log('an_record_files.json log file found and parsed for PO Receiving Alert!');
}
else{
return mkError(ferror, 'pORecAlert');
};
//finish creating JSON Object
pa = new Client();
pa.connect(ftpoptions);
console.log('FTP Connection for FTP Check Acknowledgement begun...');
pa.on('greeting', function(msg){
console.log('FTP Received Greeting from Server for ftpCheckAcknowledgement: ' + msg);
});
pa.on('ready', function(){
console.log('on ready');
//START PROMISE LIST
var listpromise = new Promise((reslp, rejlp) => {
pa.list('/public_html/test/out', false, (cerr, clist) => {
if(cerr){
return mkError(ferror, 'pORecAlert');
}
else{
console.log('Resolving clist');
reslp(clist);
}
});
});
listpromise.then((reclist) => {
ftpplist:
for(var pcl = 0; pcl < reclist.length; pcl++){
console.log('reclist iteration: ' + pcl);
console.log('checking name: ', reclist[pcl].name);
if(reclist[pcl].name.substring(0, 2) !== 'AN'){
console.log('Not AN - skipping');
continue ftpplist;
}
else{//found an AN
for(var plc = 0; plc < plogObj.length; plc++){
if(reclist[pcl].name === plogObj[plc].anname){
//console.log('Found reclist[pcl].name in local log');
anfound = true;
};
};
if(anfound === false){
console.log('Found AN file to download: ', reclist[pcl].name);
anstodownload.push(reclist[pcl].name);
};
};
};
console.log('anstodownload array:');
console.dir(anstodownload);
return anstodownload;
}).then((fnar) => {
//for simplicity/transparency, here is the array being overwritten
fnar = new Array('AN_17650_37411.699.txt', 'AN_17650_37411.700', 'AN_17650_37411.701', 'AN_17650_37411.702.txt', 'AN_17650_37411.801', 'AN_17650_37411.802.txt');
return Promise.all(fnar.map((gfname) => {
var nsalertnames = [];
console.log('Getting: ', gfname);
debugger;
pa.get(('/public_html/test/out/' + gfname), function(err, anstream){//THE PROBLEM IS THAT THIS GET GETS TRIGGERED AN EXTRA TIME FOR EVERY OTHER FILE!!!
antext = '';
console.log('Get begun for: ', gfname);
debugger;
if(err){
ferror.nsrest_trace = 'Error - could not download new AN file!';
ferror.details = err;
console.log('Error - could not download new AN file!');
console.log('************************* Exiting *************************')
logError(ferror, gfname);
}
else{
// anstream.on('data', (anchunk) => {
// console.log('Receiving data for: ', gfname);
// antext += anchunk;
// });
// anstream.on('end', () => {
// console.log('GET end for: ', gfname);
// //console.log('path to update - gfname ', gfname, '|| end text.');
// fs.appendFileSync(path.resolve('test/from', gfname), antext);
// console.log('Appended file');
// return antext;
// });//end end
};
});//get end
}));//end Promise.all and map
}).then((res99) => {
// pa.end();
// return Promise(() => {
console.log('end all. res99: ', res99);
// //res4(1);
// return 1;
// });
});
});
})();
-->> 这里发生了什么: 所以我添加了几乎可以工作的代码。发生的情况是,对于每个其他文件,都会发出一个额外的 Get 请求(我不知道它是如何被触发的),该请求失败并显示“无法建立数据连接”。
因此,对于我对这 6 个数组的迭代,最终有 9 个 Get 请求。请求元素 1(有效且预期),然后请求 2(有效且预期),然后再次请求 2(失败且意外/不知道为什么触发它)。然后是 3(工作和预期),然后是 4(工作和预期),然后是 4(失败和意外)等等
【问题讨论】:
-
请向我们展示您尝试过的实际代码,并更详细地描述您想要完成的工作。
-
在 OP 中,我添加了我为自己制作的模式示例。 settimeout 以相反的顺序运行而没有工作承诺的方式被触发。我的实际代码在我正在制作并试图重写的便便程序的旋风中。
标签: javascript node.js asynchronous ftp promise