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