В первой строке метод connect
возвращает обещание, поэтому я вызываю функцию then
(если connect
имел успех).
Почти:метод then
вызывается независимо от результата обещания connect
.Обратите внимание, что обещание, скорее всего, все еще ожидает ответа при вызове метода then
.Он называется (очевидно) синхронно .
then
принимает обратные вызовы, т.е. successCB
, failureCB
в качестве аргументов, которые фактически представляют результат или ошибку, возвращаемыеconnect
обещание.Правильно?
Эти обратные вызовы регистрируются объектом обещания, и один из них будет вызван позже, когда обещание разрешится: оно может либо выполнить, либо отклонить.Если обещание никогда не разрешится, ни один не будет вызван.В вашем случае вы предоставили только одну функцию, которая будет вызываться при выполнении обещания.
Кроме того, successCB
возвращает обещание (с .query
).
Верно.Обещание, которое было создано при выполнении внешнего then
, примет статус / значение обещания, которое было возвращено здесь.
then
снова вызывается для предыдущего обещания, возвращенного then
.
Да, но опять же, он вызывается немедленно.Все цепочечные методы then
/ catch
вызываются синхронно, и их задача - регистрировать обратные вызовы и возвращать обещание.
Асинхронная часть - это когда вызываются соответствующие обратные вызовы.Это когда каскадный эффект имеет место.Как только первое обещание (query()
) в цепочке разрешается, вызывается соответствующий обратный вызов, и этот вызов разрешает (выполняет или отклоняет) обещание , которое уже было возвращено then
, что вызывает следующий обратный вызов... и т. д.
Порядок исполнения
Часть A
sql.connect(config)
вызывает connect
и возвращает обещание
.then(......)
звонит then
по обещанию A.1, регистрирует обратный вызов и возвращает обещание
.catch(.....)
вызывает catch
по обещанию A.2, регистрирует обратный вызов и возвращает обещание.Это последний элемент в цепочке, поэтому это обещание является значением всего выражения.
На этом синхронная часть заканчивается.Если в стеке вызовов есть другой код вызова, он выполняется, но в итоге стек вызовов будет пустым.
Часть B
Затем, через некоторое время, происходит событие, указывающее, чтоОбещание А.1 решено, давайте предположим, что оно выполнено (т.е. успешно).Затем выполняется первый обратный вызов:
connection.request()
выполняется
он вызывает request
, который возвращает объект с помощью метода query
(среди прочего)
.query('select * from Users')
выполняется
, он вызывает query
с SQL и возвращает обещание
return
isвыполнено
обратный вызов возвращает обещание B.2, которое становится связанным с обещанием, созданным на шаге A.1.
На этом этапе обещаниешаг A.1 еще не завершенЕго судьба теперь связана с обещанием, которое было возвращено query
, B.2.При разрешении A.1 также разрешается (с тем же состоянием и значением / ошибкой).
Часть C
Затем, через некоторое время, происходит событие, указывающее, что обещаниешага A.1 решен, давайте предположим, что он выполняет.Затем выполняется второй обратный вызов:
console.dir(result)
выполняется res.send(result)
выполняется Ничего не возвращается, поэтому обещание 1.B выполняет со значением undefined
Это выполнение создает следующее асинхронное задание для выполнения (часть D)
Часть D
- Обещание, возвращаемое
catch
(A.3), разрешается со значением, с которым разрешен C.3, то есть выполняется со значением undefined
.Зарегистрированный обратный вызов не выполняется, поскольку он не относится к этому сценарию.