2015-02-01 4 views
0

Недавно я начал работать с обещаниями и нашел для меня странное поведение. Когда я передаю функцию .then() ссылку на неопределенную функцию, она просто пропущена, а затем вызывается.Bluebird .then(): no TypeError, когда ссылка на функцию не определена

Пример:

var cust = customer({general: { cust_id: 22 }}); // just for testing 
req.pool.getConnectionAsync() 
     .then(cust.del) // cust.del is 'undefined' 
     .then(function(dbResult) { console.log("dbresult:"); console.log(dbResult); res.status(200).end(); }) 
     .catch(function (e) { console.log(e); res.status(500).end(); }); 

Так что же здесь происходит:

  • getConnectionAsync возвращает соединение, которое должно быть дано в cust.del
  • cust.del не определено (опечатка по мне правильная функция будет cust.delete)
  • ошибка не возникает вместо следующей функции. then вызывается с соединением getConnectionAsync как «dbresu л»
  • выход последнего затем функции является объект подключения, а не результат дб объекта и состояние 200 возвращается к клиенту

Если я изменить код:

req.pool.getConnectionAsync() 
     .then(function(conn) { cust.del(conn) }) // type error is raised 
     .then(function(dbResult) { console.log("dbresult:"); console.log(dbResult); res.status(200).end(); }) 
     .catch(function (e) { console.log(e); res.status(500).end(); }); 

то я получаю ожидаемый TypeError и вызывается функция catch.

Является ли это ожидаемым поведением? Или я что-то упустил, чтобы этого не случилось? .then (cust.del), очевидно, намного более чистый код, но поскольку эта функция не вызываема, должна быть ошибка.

С уважением Фил

+3

Ожидаемое поведение: [Обещание/A +: 2.2 Тогда метод] (https://promisesaplus.com/#point-23): '[...] 2.2.1 Оба onFulfilled и onRejected являются необязательными аргументами , 2.2.1.1 Если onFulfilled не является функцией, его следует игнорировать., 2.2.1.2 Если onRejected не является функцией, его следует игнорировать. [...] ' –

+0

Большое спасибо. Я пропустил это полностью, когда прочитал это ... моя вина. – Phil147

ответ

0

Как комментарий говорит, что это похоже на:

Promise.resolve().then(undefined); // undefined is ignored here 

Указано в Обещания/A + спецификации и она работает таким образом, в каждой реализации обещания. Смысл в том, что Promises/A + не должен поддерживать метод .catch и вы могли бы сделать:

Promise.reject().then(null, function(err){ /* handle */ }); 

Как и совместимость с существующими библиотеками.

+0

«console.warn'ing, если ни один аргумент не передан, было бы неплохо. – Bergi

+0

@Bergi open [вопрос] (http://github.com/petkaantonov/bluebird/issues). Я не уверен, какой хороший вариант использования для «.then» без каких-либо обработчиков - он по-прежнему возвращает новое обещание (так что я думаю, что есть случаи отмены, где это может быть полезно), но я честно не уверен. Интересно, должна ли быть строгая сборка синей птицы, которая не допускает подобных вещей. –

+1

@Bergi 'this.then()' используется несколько раз внутри: предупреждение DA может быть полезно для не-функционального значения, которое не является нулевым или неопределенным, хотя, поскольку это 99,99%, несомненно, ошибка, но это не помогло бы этому специфический ОП, но многие другие, которые обещают. – Esailija

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