我对诺言并不陌生,已经对其进行了研究。所以我的代码和我的理解:
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
方法返回一个promise,以此类推,当我调用函数then
(如果连接成功)时。 then
采用回调,即“ successCB”,“ failureCB”作为参数,它们实际上表示connect
承诺返回的结果或错误。是吗?
此外,“ successCB”正在返回承诺(来自.query
)。
then
返回的先前的诺言上调用 then
。
在then
上使用connect()
的情况下,then
为什么要进行回调,以及如何知道connect
的成功,因为connect
具有已经返回了结果,即“ successCB”?
答案 0 :(得分:1)
如果您是正确的人,我不确定100%,但这就是我的解释方式。可以说我们有一个承诺 A 。
then()
总是会返回新的承诺(我们称其为 B )我个人觉得学习起来很混乱,因为要完全掌握它需要相当复杂的心理模型。我完全了解这一天的那天就是我编写自己的Promise
类的那一天。我建议任何完全希望兑现承诺的人都花些时间来做到这一点。
答案 1 :(得分:0)
在第一行中,
connect
方法返回一个promise,因此,我调用了一个函数then
(如果connect
成功了)。
几乎:then
方法的调用与connect
承诺的结果无关。请注意,在调用then
方法时,promise最有可能仍未完成。 (很明显)它被同步地称为 。
then
接受回调,即successCB
,failureCB
作为参数,实际上代表了connect
承诺返回的结果或错误。是吗?
这些回调由Promise对象注册,并且当Promise解析后,它们中的一个会被调用:它可以实现也可以拒绝。如果诺言永远无法解决,就不会被调用。在您的情况下,您仅提供了一个函数,当诺言履行时将调用该函数。
此外,
successCB
(从.query
返回诺言。
是的。在执行外部then
时创建的promise将接管此处返回的promise的状态/值。
再次在then
返回的先前的诺言上调用
then
。
是的,但是再次被立即调用。所有链接的then
/ catch
方法都被同步调用,它们的工作是注册回调并返回Promise。
异步部分是调用相应的回调时。这是级联效果发生的时间。链中的第一个承诺(query()
)解析后,将调用相应的回调,并且该调用解析(履行或拒绝)then
已经返回的承诺,会触发下一个回调...等等
sql.connect(config)
呼叫connect
并返回一个诺言
.then(......)
对A.1的承诺调用then
,注册回调并返回承诺
.catch(.....)
对A.2的承诺调用catch
,注册回调并返回承诺。
这恰好是链中的最后一个,所以这个承诺就是整个表达式的价值。
此时同步部分结束。如果调用堆栈上还有其他调用代码,则将执行该代码,但最终调用堆栈将为空。
然后,一段时间后,发生一个事件,表明A.1的承诺已解决,我们假设它已实现(即成功)。然后执行第一个回调:
connection.request()
被执行
它调用request
并返回一个带有query
方法的对象(以及其他方法)
.query('select * from Users')
被执行
它使用SQL调用query
并返回一个诺言
return
被执行
回调返回B.2的承诺,该承诺与在步骤A.1中创建的承诺链接。
这时,步骤A.1的承诺仍未完成。现在,它的命运与query
B.2返回的诺言紧密相关。一旦解决,A.1也将解决(具有相同的状态和值/错误)。
然后,一段时间后,发生一个事件,表明步骤A.1的承诺已解决,我们假设它已实现。然后执行第二个回调:
console.dir(result)
被执行res.send(result)
被执行不返回任何内容,因此1.B的诺言实现为值undefined
此实现会创建要执行的下一个异步作业(D部分)
catch
(A.3)返回的诺言以C.3解析的值来解析,即,它以值undefined
来履行。已注册的回调不执行,因为它与该场景无关。答案 2 :(得分:0)
感谢您的答复,我已经选择了答案。根据大家的意见,这是我进一步了解的。
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
对象)和更高版本
.then(function(result) {
console.dir(result);
res.send(result);
}).
在上一个。promise
方法的回调函数的.query('select * from Users')
部分返回的then()
上调用。