2016-11-20 17 views
1

ブルーバードの約束を使用してかなり新しいです。私はそれらをエミッタ上で使用しようとしていました。しかし、私はエラーを処理する方法に固執しています。イベントエミッタでブルーバード約束

私はエミッタであるstreamオブジェクトを持っています。コードは以下の通りである -

return new Promise((resolve, reject) => { 

    var onDocFunc = doc => { 
     //JSON.parse('*'); 
     // some logic goes in here to construct setStmt 
     bulk.find(query).upsert().update({$set: setStmt}); 
     count++; 
     if (count % bulkSize == 0) { 
      stream.pause(); 
      var execute = Promise.promisify(bulk.execute); 
      execute().catch(() => {}).then(() => { 
       stream.resume(); 
      }); 
     } 
    }; 

    stream.on('data', onDocFunc); 

    stream.on('end',() => { 
     JSON.parse('*'); // how to catch errors that happen here?? 
     var boundResolve = resolve.bind(this, {count: count}); 
     if (count % bulkSize != 0) { 
      Promise.promisify(bulk.execute)().then(boundResolve).catch(boundResolve); 
     } 
     else { 
      boundResolve(); 
     } 
    }); 

    stream.on('error', err => { 
     reject(err); 
    }); 

}) 

私はendイベントハンドラのコールバック内で発生したエラーをキャッチするために推奨される方法が何であるかを知りたいですか?何らかのエラーがuncaughtException: Unexpected token *

答えて

3

は、イベント・エミッターのpromisificationにアプリケーションロジックを混在させないでください。そのようなコード(それを投げるなど)は常にthenコールバックに入るべきです。あなたのケースでは:

var execute = Promise.promisify(bulk.execute); 
return new Promise((resolve, reject) => { 
    stream.on('data', onDocFunc); // not sure what this does 
    stream.on('end', resolve); 
    stream.on('error', reject); 
}).then(() => { 
    JSON.parse('*'); // exceptions that happen here are caught implicitly! 
    var result = {count: count}; 
    if (count % bulkSize != 0) { 
     return execute().catch(()=>{}).return(result); 
    } else { 
     return result; 
    } 
}); 

あなたの実際のコードについては、私はおそらくヘルパー関数にバッチ処理を考慮してみたい:

function asyncBatch(stream, size, callback) { 
    var batch = [], count = 0; 
    stream.on('data', data => { 
     batch.push(data); 
     count++; 
     if (batch.length == size) { 
      stream.pause(); 
      Promise.resolve(batch).then(callback).then(() => { 
       batch = []; 
       stream.resume(); 
      }, e => { 
       stream.emit('error', e); 
      }); 
     } 
    }); 
    return new Promise((resolve, reject) => { 
     stream.on('end', resolve); 
     stream.on('error', reject); 
    }).then(() => batch.length ? callback(batch) : null).then(() => count); 
} 

Promise.promisifyAll(Bulk); 
return asyncBatch(stream, bulkSize, docs => { 
    const bulk = new Bulk() 
    for (const doc of docs) { 
     // JSON.parse('*'); 
     // some logic goes in here to construct setStmt 
     bulk.find(query).upsert().update({$set: setStmt}); 
    } 
    return bulk.executeAsync().catch(err => {/* ignore */}); 
}) 
+0

これはきれいに見えます。洞察に感謝します。これを覚えておいてください。 – hyades

+0

'onDocFunc'の中で' JSON.parse'のような例外を処理しなければならない場合はどうしたらいいですか? – hyades

+0

'try'-' catch 'ブロックを実行しますが、そこに 'JSON.parse'が必要であると私は確信していません。質問にあなたが実際に行っていることのコード全体を投稿できるのであれば、私は自分の答えを更新することができます。 – Bergi

0

で、NodeJSアプリケーションのクラッシュが発生した場合、今あなたは、try/catchブロックを使用する必要があります:

stream.on('end',() => { 
    try { 
    JSON.parse('*') 
    // ...the rest of your code 
    } catch (e) { 
    reject(e) 
    } 
}) 
+0

いやでも私は 'てみ-catch'考えます。しかし、私は今これらのブロックですべてのコールバックを囲む必要があるので、それを使用するとコードがちょっと乱雑になります。このような状況に対処するのはこれだけですか? – hyades

+1

@hyadesあなたがしなければならないことは、あなたが 'end'イベントコールバックですぐに持っているデータを解決することです。次に、あなたの約束に '.then()'ハンドラを追加し、その中に 'JSON.parse()'の処理を行います。その後、エラーが「キャッチ」され、返された約束が拒否されます。 – idbehold

+0

ええ、ただ@bergiが言ったことをしてください。 – idbehold

関連する問題