Возвращает ли функция then () обещание, отражающее результаты предыдущего обещания? - PullRequest
0 голосов
/ 15 февраля 2019

Я новичок в обещаниях и изучил его.Итак, мой код и мое понимание:

sql.connect(config).then(function(connection) {
  return connection.request().query('select * from Users')
}).then(function(result) {
  console.dir(result);
  res.send(result);
}).catch((err) => {
  console.log(err);
  res.send(err)
});
}) // extra?

В первой строке метод connect возвращает обещание, поэтому при вызове функции then (, если подключение прошло успешно ).then принимает обратные вызовы, т.е. "successCB", "failCB" в качестве аргументов, которые фактически представляют результат или ошибку, возвращенную обещанием connect.Правильно?

Кроме того, «successCB» возвращает обещание (из .query).

then снова вызывается для предыдущего обещания, возвращенного then.

В случае then, используемого на connect(), почему then принимает обратный вызов и как он узнает об успехе connect, поскольку connect уже вернул результат, то есть "successCB"?

Ответы [ 3 ]

0 голосов
/ 15 февраля 2019

В первой строке метод connect возвращает обещание, поэтому я вызываю функцию then (если connect имел успех).

Почти:метод then вызывается независимо от результата обещания connect.Обратите внимание, что обещание, скорее всего, все еще ожидает ответа при вызове метода then.Он называется (очевидно) синхронно .

then принимает обратные вызовы, т.е. successCB, failureCB в качестве аргументов, которые фактически представляют результат или ошибку, возвращаемыеconnect обещание.Правильно?

Эти обратные вызовы регистрируются объектом обещания, и один из них будет вызван позже, когда обещание разрешится: оно может либо выполнить, либо отклонить.Если обещание никогда не разрешится, ни один не будет вызван.В вашем случае вы предоставили только одну функцию, которая будет вызываться при выполнении обещания.

Кроме того, successCB возвращает обещание (с .query).

Верно.Обещание, которое было создано при выполнении внешнего then, примет статус / значение обещания, которое было возвращено здесь.

then снова вызывается для предыдущего обещания, возвращенного then.

Да, но опять же, он вызывается немедленно.Все цепочечные методы then / catch вызываются синхронно, и их задача - регистрировать обратные вызовы и возвращать обещание.

Асинхронная часть - это когда вызываются соответствующие обратные вызовы.Это когда каскадный эффект имеет место.Как только первое обещание (query()) в цепочке разрешается, вызывается соответствующий обратный вызов, и этот вызов разрешает (выполняет или отклоняет) обещание , которое уже было возвращено then, что вызывает следующий обратный вызов... и т. д.

Порядок исполнения

Часть A

  1. sql.connect(config)

    вызывает connect и возвращает обещание

  2. .then(......)

    звонит then по обещанию A.1, регистрирует обратный вызов и возвращает обещание

  3. .catch(.....)

    вызывает catch по обещанию A.2, регистрирует обратный вызов и возвращает обещание.Это последний элемент в цепочке, поэтому это обещание является значением всего выражения.

На этом синхронная часть заканчивается.Если в стеке вызовов есть другой код вызова, он выполняется, но в итоге стек вызовов будет пустым.

Часть B

Затем, через некоторое время, происходит событие, указывающее, чтоОбещание А.1 решено, давайте предположим, что оно выполнено (т.е. успешно).Затем выполняется первый обратный вызов:

  1. connection.request() выполняется

    он вызывает request, который возвращает объект с помощью метода query (среди прочего)

  2. .query('select * from Users') выполняется

    , он вызывает query с SQL и возвращает обещание

  3. return isвыполнено

    обратный вызов возвращает обещание B.2, которое становится связанным с обещанием, созданным на шаге A.1.

На этом этапе обещаниешаг A.1 еще не завершенЕго судьба теперь связана с обещанием, которое было возвращено query, B.2.При разрешении A.1 также разрешается (с тем же состоянием и значением / ошибкой).

Часть C

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

  1. console.dir(result) выполняется
  2. res.send(result) выполняется
  3. Ничего не возвращается, поэтому обещание 1.B выполняет со значением undefined

    Это выполнение создает следующее асинхронное задание для выполнения (часть D)

Часть D

  1. Обещание, возвращаемое catch (A.3), разрешается со значением, с которым разрешен C.3, то есть выполняется со значением undefined.Зарегистрированный обратный вызов не выполняется, поскольку он не относится к этому сценарию.
0 голосов
/ 19 февраля 2019

Спасибо за ответы, и я уже выбрал ответ.Исходя из того, что дали вам, люди, это то, что я понял далее.

sql.connect(config).then(function(connection) {
  return connection.request().query('select * from Users')
})

В приведенном выше коде часть sql.connect использует модуль SQL для вызова метода connect(), которыйдолжен возвращать promise (в случае сбоя возвращает ошибку, иначе объект connection).На connect() мы вызываем метод then(), который принимает функцию обратного вызова function(connection) для регистрации, которая может быть вызвана позже в точке, где connect возвращает promise (в случае success, то есть connection object) и позже

.then(function(result) {
  console.dir(result);
  res.send(result);
}).

вызывается на promise, возвращаемом .query('select * from Users') частью предыдущего. then() функция обратного вызова метода и т. д.

0 голосов
/ 15 февраля 2019

Я не уверен на 100%, если вы правы, но я бы так объяснил.Допустим, у нас есть обещание A .

  • Вызов then() всегда возвращает новое обещание (назовем его B )
  • Если обратный вызов возвращает обещание C , то обещание B разрешится или не выполнится с результатом обещания C .
  • Если какой-либо из обратных вызовов возвращает значение без обещания X , то обещание B разрешится со значением X
  • Если исключениебыл брошен в обратном вызове, тогда обещание B не выполнится с исключением.
  • Если основное обещание A не выполнено и обратный вызов не был выполнен, то обещание B также потерпит неудачу с той же ошибкой.

Лично я нахожу изучение этого очень запутанным, потому что для его полного понимания требуется довольно сложная ментальная модель.День, когда я полностью понял, это день, когда я написал свой класс Promise.Я бы порекомендовал любому, кто полностью хочет понять обещания в каждой детали, чтобы найти время, чтобы сделать это.

...