2016-11-20 4 views
1

Ich bin ziemlich neu mit der Verwendung von Bluebird verspricht. Ich habe versucht, sie über einen Emitter zu verwenden. Ich bin jedoch fest, wie mit Fehlern umzugehen ist.Bluebird Promises mit Event Emitter

Ich habe ein stream Objekt, das der Emitter ist. Code ist wie unten -

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); 
    }); 

}) 

Ich möchte wissen, was der empfohlene Weg ist, einen Fehler zu fangen, die innerhalb der Rückruf des end Ereignishandler auftritt? Gerade jetzt, wenn ein Fehler auftritt, werden die NodeJS Anwendung abstürzt mit uncaughtException: Unexpected token *

Antwort

3

Sie nicht die Anwendungslogik in die promisification des Ereignisses Emitter mischen. Solcher Code (der kann usw. werfen) sollte immer in then Callbacks gehen. In Ihrem Fall:

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; 
    } 
}); 

In Bezug auf Ihrem echten Code, würde ich wahrscheinlich versuchen, die Dosierung in eine Hilfsfunktion Faktor aus:

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

Das sieht ordentlich aus. Danke für die Einblicke. Behalte dies im Hinterkopf. – hyades

+0

Wenn ich Ausnahmen wie die 'JSON.parse' in' onDocFunc' behandeln muss, was soll ich tun? – hyades

+0

Gehen Sie zu 'try'-' catch' Blöcken, obwohl ich nicht davon überzeugt bin, dass Sie tatsächlich die 'JSON.parse' darin brauchen. Wenn Sie den gesamten Code dessen, was Sie tatsächlich in Ihrer Frage tun, veröffentlichen können, kann ich meine Antwort aktualisieren. – Bergi

0

Sie werden einen try/catch-Block verwenden müssen:

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

Ja sogar ich dachte 'Try-catch' . Allerdings macht es den Code etwas unordentlich, da ich nun alle Callbacks mit diesen Blöcken umschließen muss. Ist dies der einzige Weg, um mit einer solchen Situation umzugehen? – hyades

+1

@hyades gut, was Sie wahrscheinlich tun sollten, ist, lösen Sie alle Daten, die Sie sofort in der 'Ende' Event-Callback haben. Dann fügen Sie einen '.then()' Handler zu Ihrem Versprechen hinzu und machen Sie das 'JSON.parse()' Zeug darin. Dann werden alle Fehler "gefangen" und bewirken, dass das zurückgegebene Versprechen zurückgewiesen wird. – idbehold

+0

Ja, mach einfach was @bergi gesagt hat. – idbehold

Verwandte Themen