2016-11-20 146 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

然後嘗試''''''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很好你應該做的是解決你立即在'結束'事件回調的任何數據。然後在你的承諾中添加一個'.then()'處理程序,並在其中執行'JSON.parse()'東西。那麼任何錯誤都將被「抓住」並導致退回的承諾被拒絕。 – idbehold

+0

是的,只要做@bergi說的。 – idbehold