2017-05-31 8 views
0

私は働いている(私はこれをすべて間違って行うことができます)機能に固執しています。だから簡単な説明、私はコレクション内の一括データを追加したい、コレクションは "サイト"と呼ばれ、CSVのフォーマットは、サイト、国、タイプです。私はこれに約束を使用しようとしている(ブルーバード)。だから、コードを検討:({: 'OK' を、メッセージ:ステータスが ''})Promise.Eachを使用しているマングースとBluebird

Promise.each(sites, sites => new Promise((resolve, reject) => { 
    //console.log(sites); 
    let name = tools.extractDomain(req, res, sites[0]); 
    let country = sites[1]; 
    let group = sites[2]; 
    if (name != "" && country != "" && group != "") { 

     Site.findOne({ name: name }, "_id", function(err, duplicate) { 
      if (false) { 
       console.log("Duplicate site: " + duplicate); 

      } else { 
        //console.log("Adding " + name) 
       let site = new Site() 
       site.name = name 
       site.meta = {} 
       site.group = group 
       site.country = country 
       site.geomix = [] 
       site.addedBy = req.user._id 
       site.addedAt = Date.now() 
       site.saveAsync().then(function(response){ 
        tools.saveHistory(req, res, response._id, response.name, "Website Meta fetched."); 
        tools.saveHistory(req, res, response._id, response.name, "Link added for the first time."); //Save in history 
        resolve(site); 
       }).catch(function (e){ 
        console.log(name); 
        reject(); 
       }); 
      } 
     }); 

    }else{ 
     console.log('Wrong Format'); 
    } 
}).then((data) => { 
     console.log('All websites processed!'); 
     addedSites.push(data); 
}).catch(err => { 
     //console.error('Failed'); 
})); 

    res.send({ status: 'ok', message: ''}); 

を私はアヤックスが、私はres.sendを返すので、呼び出して作ってるんだ、私が知っているその間違った場所にしてI res.sendに沿っていくつかのデータを送信したい。現在、コードが実際に終了する前にヘッダーを送信します。私はすべてのデータがMongoで追加された後にヘッダを送信したいが、この場合はそれぞれのために解決する()ので、 ".each"の ".then"の中にヘッダを送ると、ヘッダがすでに送られる。

これは少し混乱するかもしれません。私はこの権利をしていないと感じている。私は少し狂っただけでなく、私が理解して実装できる適切な例を見つけることができません。

最後に、私の主な質問は、Ajaxコールを使用して、約束事を使って1000レコードを追加し、実際には追加できなかった人とそうでない人を適切に制御するということです。

今のところ私のコードは実際に動作しますが、論理は間違っています。

ありがとうございました。

+1

[ 'Promise'コンストラクタアンチパターン](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-を避けてくださいそれ)!あなたが 'Site.findOne'を約束する必要がある場合は、それを別の関数で行います(または、Bluebirdがそれをあなたに任せます)。 – Bergi

答えて

0

bulkWriteは、お使いのモデルに使用できます。

参考:http://mongoosejs.com/docs/api.html#model_Model.bulkWrite

編集:私はあなたを誤解

申し訳ありません。

Promise.each(sites, sites => new Promise((resolve, reject) => { 
    // stuff you did before 
}).then((data) => { 
    console.log('All websites processed!'); 
    addedSites.push(data); 
    res.send({ status: 'ok', message: ''}); 
}).catch(err => { 
    res.send({ status: 'failed', message: err.message}); 
})); 
+0

それが役立つかどうかわかりません。私はその機能を認識しており、私はまだそれを使用することができます私はまだ混乱していると私のポイントは、約束とバルクとエラーを処理する適切な方法を理解することです。私がbulkWriteを実装しても、私はまだ同じ問題を抱えています。 – DanielPanic

+0

それは良いですが、私はまだその結論に達しました。しかし、これをチェックする毎回私は解決()を持っているので、毎回そのヘッダーを送信してコードが実際に動作する前に(フロントエンドの私の場合、status.okと私はユーザーに警告を送ります私はそのres.sendを置く場合、データとdom)。私は追加するレコードのサイズを数えることでそれを修正し、両方が一致したときにインクリメントを持っています。私はヘッダーを送信します。もしそれが最もエレガントな方法であるかどうかわからない – DanielPanic

0

これは良いアーチであれば、誰かが私に言うことができる場合、これは、私があまりにも来たものです:あなたはこのような何かを取得しますので、res.send({ status: 'ok', message: ''});then()へとcatch()ブロックを移動する必要があります。

exports.addBulkSite = function(req, res, next) { 
    let siteArray = csv.parse((req.body.sites).trim()), 
     addedSites = [], 
     failedSites = [], 
     duplicated = [], 
     sites = siteArray, 
     size = sites.length, 
     processed = 0, 
     meta; 
    Promise.each(sites, sites => new Promise((resolve, reject) => { 
     let name = tools.extractDomain(req, res, sites[0]), 
      country = sites[1], 
      group = sites[2]; 
     if (name != "" && country != "" && group != "") { 
      Site.findOneAsync({ name: name }, "_id").then(function(duplicate) { 
       duplicated.push(duplicate); 
       reject({name:name, message: 'Duplicated', critical:false});   
      }).catch(function(notDuplicated){ 
       let site = new Site() 
       site = { 
          name: name, 
          meta: {}, 
          group: group, 
          country: country, geomix:{}, 
          addedBy: req.user._id, 
          addedAt:Date.now() 
         } 
       site.saveAsync().then(function(response){ 
        tools.saveHistory(req, res, response._id, response.name, "Website Meta fetched."); 
        tools.saveHistory(req, res, response._id, response.name, "Link added for the first time."); //Save in history 
        resolve(site); 
       }).catch(function (e){ 
        console.log(e); 
        reject({name:name, message: 'Error saving in the database. Please contact the administrator.', critical: true}); 
       }); 
      }); 
     }else{ 
      reject({name:name, message: 'Paramaters are missing', critical:false}); 
     } 
    }).then((data) => { 
      processed++; 
      addedSites.push(data); 
      if(processed==size){ 
      console.log('out'); 
      res.send({ status: 'ok', addedSites: addedSites, failedSites: failedSites, duplicated: duplicated}); 
      } 
    }).catch((err) => { 
      processed++; 
      console.log(err); 
      failedSites.push(err); 
      if(processed==size){ 
      console.log('out'); 
      res.send({ status: 'ok', addedSites: addedSites, failedSites: failedSites, duplicated: duplicated}); 
      } 
    })); 
} 
+1

とにかく 'findOneAsync'を使うときは、' 'Promise''コンストラクタの反パターンを避けてください(https://stackoverflow.com/q/23803743/1048572?What-is-the - プロミス - 建設 - 反パターン - と - どのように回避する - それ)! – Bergi

+0

私はそれについていくつかのことを読んでいますが、理解しにくいと私のコードに書いておくことを約束してくれることを新たにしています。それでも正しい方向を意味するので、まだいくつかの研究を行い、あなたのヒントは本当に役に立つものです。ありがとう。 – DanielPanic

+0

新しいプロミス((resolve、reject)=> {'部分を削除し、代わりに値を返すか、約束を返す(拒否の場合は' throw') – Bergi

関連する問題