2017-01-16 12 views
0

私は、指定された設定ファイルに従って約束をループで作成し、すべてが解決されたら応答を返す必要があります。ここにコードがあります。ループ内で約束を作成

{for(let type in spotlight){ 
    switch (type){ 
     case "outliers":{ 
       let ops= spotlight[type]; 
       for(let i=0;i<ops.length;i++){ 
        (function(op){ 
         let p= new Promise(function(resolve,reject){ 
          let reqUrl= urlCreator(op.uri,op.query); 
          //console.log("--------------------"+reqUrl); 

          apiService.get(reqUrl,function(isSuccess,data){ 
           if(!isSuccess){ 
            return reject(data); 
           } 
           // console.log(isSuccess); 
           // console.log(data); 
           // console.log("trend is ------"+JSON.stringify(op)); 
           // create objects array 
           // let temp= []; 
           // let overallScore= data.overall.score; 
           // for(let day in overallScore){ 
           //  temp.push({"key": day,"value": parseFloat(overallScore[day])}); 
           // } 
           //let outliers= stats.outliers(temp,"key","value"); 
           resolve({"type":type,"name": op.name,"data": outliers}); 

          }) 
         }); 
         promiseArray.push(p); 
        }(ops[i]))   
       } 
       break;  
      } 

     case "filters":{ 
       let ops= spotlight[type]; 
       for(let i=0;i<ops.length;i++){ 
        (function(op){ 
         let p= new Promise(function(resolve,reject){ 
          let reqUrl= urlCreator(op.uri,op.query); 
          apiService.get(reqUrl,function(isSuccess,data){ 
           if(!isSuccess){ 
            return reject(data); 
           } 
           // console.log(isSuccess); 
           // console.log(data); 
           // console.log("coc is ------"+JSON.stringify(op)); 
           resolve({"type": type,"name": op.name,"data": data}); 

          }) 
         }) 
         promiseArray.push(p); 
        }(ops[i])) 
       } 
      break;  
      } 
    } 
} 

Promise.all(promiseArray).then(values=>{ 
    return res.json(values); 
}, 
reason=>{ 

    return res.json(reason); 
}).catch(reason=>{ 
    return res.json(reason); 
})} 

問題は、決して返されず、解決も拒否もされません。
設定ファイルによれば、u1とu2の2つのURLにヒットする必要があります。私は出力をログに記録して、どのリクエストが返ってきたのかを確認しようとしましたサーバーが開始され、非常に最初のreqが行われると、U1が戻り、reqがハングします。リフレッシュすると、私はU2、U2からの応答を得て、リクエストがハングした後、再びリフレッシュしてU1、U1をリフレッシュし、これが続きます。何らかの理由で1つのリクエストだけが返され、他のリクエストはバッファや何かに座って次のリクエストが行われたときに来るようです。どちらのリクエストもローカルサーバーに対してのみ行われています。私は、URLがキャッシュのキーとして使用されているので、キャッシュを使用するために外部にルーティングしています。
facebook.comやgoogle.comのようなダミーのURLを使ってみましたが、それは完全にうまく動作します。ローカルURLを1つ使用し、facebook.comも同様に動作しますが、両方のURLがローカルサーバーの場合はスタックされます。
ノードのシングルスレッドの性質や、両方の要求を行うために同じソケットを使用することが関係していますか。
PS-私はURL呼び出しを行うためにnpm-requestを使用しています。

答えて

0

おそらく、2回目のリクエストをする前に躊躇して、あなたの問題を解決できます。

私はそれに役立つツールをいくつか作っています。 requestfunction(error , response)のように定義されたエラーの最初のコールバックを、消費しながら、あなたがfunction(success , data)としてrequestコールバックを定義している

https://github.com/J-Adrian-Zimmer/JavascriptPromisesClarified.git

0

でMacroQTools.jsファイルを参照してください。

あなたは次のようにリクエストを呼び出している:最初のパラメータミスならば、あなたは、二番目のパラメータでデータを、それを拒否しなければならない、というふり

apiService.get(reqUrl,function(isSuccess,data){ 
    if(!isSuccess){ 
     return reject(data); 
    } 
    // console.log(isSuccess); 
    // console.log(data); 
    // console.log("coc is ------"+JSON.stringify(op)); 
    resolve({"type": type,"name": op.name,"data": data}); 

}); 

。一方では、実際に、それは希望のようなもの:request以来

apiService.get(reqUrl,function(err,data){ 
    if(err){ 
     reject(err); 
    } 
    else{ 
     // console.log(isSuccess); 
     // console.log(data); 
     // console.log("coc is ------"+JSON.stringify(op)); 
     resolve({"type": type,"name": op.name,"data": data}); 
    } 

}); 

がエラー最初のコールバック(コールバックを取るノードのようにほとんど何を)期待しています。だから、

、期待通りの要求が実際にあなたのコードが実際にrequest作品、isSuccessがnullで、dataは、実際の応答値を持っているときから、実際の実際の値との約束を拒否しなければならない、働きます。 あなたのリクエストはあなたのapiの設定上の問題が原因で変わっていると思います。要求が成功したときに約束を拒否する(却下理由としてデータをsendとする)。

また、Promise.all()の拒否を2回処理し、もう1つのハンドラをthenに渡して、もう一度catchを呼び出します。 1つだけが必要で、.catch(handler)is probably betterです。

Promise.allを使用して非同期要求を収集する方法について、小さな実例を作成しました。apiServiceとしてimdbを使用しましたが、すべての非同期HTTPサービスも機能します。あなたのコードから完全に再現することはできませんでしたが、コードを動作させるためにこれを適応させることができます。少なくとも、HTTPサービスを消費しているコードの少なくとも一部。

var express = require('express'); 
var app = express(); 
var Promise = require('bluebird'); 
var imdb = require('imdb-api'); 

app.get('/', controllerHandler); 

app.listen(3000, function() { 
    console.log('Example app listening on port 3000!') 
}); 


var apiService = {} 
apiService.get = imdb.getReq; 


function controllerHandler(request , response){ 
    //like iterating through spotlight.type and returning an array of promises from it. 
    //in this case the array is from films and Airbag is obviously the best of them 
    var promises = [{name : 'The Matrix'} , { name : 'Avatar'} , {name : 'Airbag'}].map(createPromise); 

    //use either .catch(errorHandler) or then(successHandler , errorHandler). The former is the better: 
    Promise.all(promises).then(successHandler).catch(errorHandler); 

    function successHandler(result){ 
     return response.json(result); 
    } 

    function errorHandler(reason){ 
     console.log('There was an error calling to the service:'); 
     console.log(reason); 
     return response.send('there was an error'); 
    } 
} 

function createPromise(film){ 
    return new Promise(function(resolve , reject){ 
     apiService.get(film , function(err , data){ 
      if(err) 
       reject(new Error(err)); 
      else 
       resolve({title : data.title , year : data.year}); 
     }); 
    }); 
};