2016-01-14 2 views
0

Дано:Использование же поймать блок для нескольких методов, то

  • NodeJS v0.10.25
  • Все особенности Harmony включен
  • "use strict"

И следующий код:

db.connect({ 
     host: DB_HOST, 
     port: DB_PORT 
    }).then(function(dbConn) { 
     console.log('DBASE connected to ' + DB_HOST + ':' + DB_PORT); 
     db.dbList().run(dbConn).then(function(result) { 
     if (result.indexOf(SCRIPT_NAME) == -1) throw new Error('unable to locate database ' + SCRIPT_NAME); 
     dbConn.use(SCRIPT_NAME); 
     console.log('DBASE bound to ' + SCRIPT_NAME + ' on ' + DB_HOST + ':' + DB_PORT); 
     db.tableList().run(dbConn) 
      .then(function(result) { 
      if (!result) throw new Error(SCRIPT_NAME + ' unable to enumerate tables'); 
      if (!result.length) throw new Error(SCRIPT_NAME + ' has no tables'); 
      console.log('DBASE ' + DB_HOST + ':' + DB_PORT + '/' + SCRIPT_NAME + ' has ' + result.length + ' table' + ((result.length > 1) ? 's' : '')); 
      }).catch(function(err) { 
      console.error('DBASE ' + err); 
      }); 
     }).catch(function(err) { 
     console.error('DBASE ' + err); 
     }); 
    }).catch(function(err) { 
     console.error('DBASE ' + err); 
    }); 

Обратите внимание на множитель е тождественны уловах блоки:

.catch(function(err) { 
      console.error('DBASE ' + err); 
     }); 

Существует ли рекомендуемый/принятые/де-факто способ повторно использовать этот обработчик исключений на нескольких уровнях структуры управления?

ответ

1

Ошибка будет пузырь, пока они поймали, так что вам не нужны несколько уловов, и вы можете сделать ваш код более читаемым, приковав свои обещания, а не гнездятся их: ответ

db.connect({ 
    host: DB_HOST, 
    port: DB_PORT 
}).then(function(dbConn) { 
    console.log('DBASE connected to ' + DB_HOST + ':' + DB_PORT); 
    // it's important to return if you have a promise so the chain doesn't break 
    return db.dbList().run(dbConn); 
}).then(function(result) { 
    if (result.indexOf(SCRIPT_NAME) == -1) throw new Error('unable to locate database ' + SCRIPT_NAME); 
    dbConn.use(SCRIPT_NAME); 
    console.log('DBASE bound to ' + SCRIPT_NAME + ' on ' + DB_HOST + ':' + DB_PORT); 
    return db.tableList().run(dbConn); 
}).then(function(result) { 
    if (!result) throw new Error(SCRIPT_NAME + ' unable to enumerate tables'); 
    if (!result.length) throw new Error(SCRIPT_NAME + ' has no tables'); 
    console.log('DBASE ' + DB_HOST + ':' + DB_PORT + '/' + SCRIPT_NAME + ' has ' + result.length + ' table' + ((result.length > 1) ? 's' : '')); 
}).catch(function(err) { 
    console.error('DBASE ' + err); 
}); 
0

Сяньшаня является правильным, но так как вы сказали, что вы используете ES2015 на современном узле вы можете использовать более современный синтаксис:

db.connect({ 
    host: DB_HOST, 
    port: DB_PORT 
}).then(dbConn => { 
    console.log(`DBASE connected to ${DB_HOST} : ${DB_PORT}`); 
    return db.dbList().run(dbConn); 
}).then(result =>{ 
    if (!result.includes(SCRIPT_NAME)) 
    throw new Error(`unable to locate database ${SCRIPT_NAME}`); 
    dbConn.use(SCRIPT_NAME); 
    console.log(`DBASE bound to ${SCRIPT_NAME} on ${DB_HOST} : ${DB_PORT}`); 
    return db.tableList().run(dbConn); 
}).then(result => 
    if (!result) throw new Error(`${SCRIPT_NAME} unable to enumerate tables`); 
    if (!result.length) throw new Error(`${SCRIPT_NAME has no tables`); 
    console.log(`DBASE ${DB_HOST} : ${DB_PORT}/${SCRIPT_NAME} has ` + ` 
       `${result.length} table ${((result.length > 1) ? 's' : '')}`); 

process.on('unhandledRejection', (p) => console.error('DBASE', p)); // global handler 

еще дальше, если мы используем генератор насос, код можно записать в виде:

function co(gen) { // your friendly neighborhood generator pump 
    var it = gen(); 
    return Promise.resolve().then(function next(v){ 
     let r = it.next(v); 
     if(r.done) return r.value; 
     return Promise.resolve(r.value).then(next, e => it.throw(e)); 
    }); 
} 

co(function*() { // console logs ommitted for brevity 
    const db = yield db.connect({host: DB_HOST, port: DB_PORT }); 
    const list = yield db.dbList().run(dbConn); 
    if(!result.includes(SCRIPT_NAME)) 
    throw new Error(`unable to locate database ${SCRIPT_NAME}`); 
    db.use(SCRIPT_NAME); 
    const tables = db.tableList().run(db); 
    if(!tables) throw new Error(`${SCRIPT_NAME} unable to enumerate tables`); 
    if(!tables.length) throw new Error(`${SCRIPT_NAME} has no tables`); 
    return tables; // this still returns a promise, you can chain off it 
}); 

И все, полностью плоский, вы можете использовать синхронный try/catch там, и он будет работать, а также использовать .catch по полученному обещанию, если вы предпочитаете.

Вы можете использовать библиотеку, такую ​​как bluebird для сопрограммы, вместо указанной выше функции co, которая даст вам лучшие трассировки стека и более быстрые обещания.

Смежные вопросы