2016-05-26 15 views
-1

私は約束が新しく、そこには答え/パターンがあると確信していますが、私は正しいものであることが分かりました。私はnode.jsを使用しています。v4.2.4とhttps://www.promisejs.org/node.js GETs with promise

これはかなり簡単ですね...特定の順序で複数の非同期ブロックを実行する必要があり、中間ブロックの1つがHTTP GETの配列

//新しい約束= asyncblock1 - FTP一覧、返されたリストの配列 //.then(asynchblock2(list))解決 - 。リストの配列をループし、HTTP GET必要なファイル //を、その後(asynchblock3( list)) - ローカルログを更新

新しいPromiseを作成して解決し、リストを.thenに渡してGETループを実行してからファイルを更新しようとしました。私はasynchblock2内でネストされたpromise.allを使用しようとしましたが、実際にはそれらのイベントのタイミングのために3と2と1の逆順になります。助けてくれてありがとう。

EDIT:これは私が使用しているパターンです。私はちょうど真ん中の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); 
    }); 
}); 

EDITはほとんど動作するコードです!

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(正常に動作し、予期しない)などのエラーが表示されます。

+0

お試しの実際のコードを表示し、達成しようとしていることを正確に説明してください。 – jfriend00

+0

OPでは、自分で作ったパターンの例を追加しました。 settimeoutは動作可能な約束なしに逆の順序で実行されるようにトリガされます。私の実際のコードは、私が作って書き直そうとしているプープログラムの旋風の中にあります。 – ejbones

答えて

0

https://github.com/caolan/asyncPromise.all()、アプリのサンプルコードです:

... 
}).then(() => { 
    return Promise.all(arry.map(item => ftpclient.getFile(item))) 
}).then((resultArray) => { 
... 
+0

これはうまくいきますが、私の最後の問題は何とか余分なGETリクエストがトリガされ、うまくいきません。すべてのファイルがダウンロードされますが、余分なGET要求がどのようにトリガーされているかはわかりません。 OPを編集する – ejbones

-1

非同期ライブラリが必要です。ループ内で非同期操作を使用する必要がある状況でasync.eachSeriesを使用し、それらのすべてが完了したら関数を実行します。あなたが望むフローに応じて多くのバリエーションがありますが、このライブラリはすべてそれを行います。あなたが必要なもの

async.each(theArrayToLoop, function(item, callback) { 
// Perform async operation on item here. 
    doSomethingAsync(item).then(function(){ 
    callback(); 
    }) 
}, function(err){ 
    //All your async calls are finished continue along here 
}); 
0

だから、助けてくれてありがとう(無便利方向と反対票!)

私は実際に良いnodejsプログラマに手を差し伸べました。彼は私が使っていたftpモジュールにバグがあるようだと言っていました。そして、blackbir d .mapでは、リクエストの迅速な連続が何とかエラーを開始しました。 promise-ftp、blackbird、promiseTaksQueueを使用して終了しました。キッカーは間隔が必要でした。それがなければ、ftpはftpモジュールに異常な非論理的なエラーを引き起こすでしょう。