承诺和承诺链是如何工作的? [代码问题]
How promises and promise chaining works? [Problem with code]
我正在学习 Node.js 并尝试正确使用 mysql2 模块。因此,我最近开始研究承诺。
我正在写一种 "library",这样我就可以练习所有这些主题,而在这样做的同时,我遇到了一个我无法真正理解的承诺链问题。非常感谢任何帮助!
问题如下:
假设我有一个 query
函数来获取数据库、处理数据和 return 一个承诺,这样我就可以获取该数据并在其他文件中使用它。
现在,如果我这样写 query
函数:
query(){
let p = new Promise((resolve, reject) => {
resolve("Hello world")
});
p.then(data => {
console.log("Hello world a second time!");
}).then(data => {
console.log("Hello world a third time")
})
return p;
}
我尝试 "consume" 来自其他文件的承诺,如下所示:
DBObject.query().then((data) => {
console.log("Hello world from the other file!");
})
然后输出顺序错误,程序打印如下:
Hello world a second time!
Hello world from the other file!
Hello world a third time
另一方面,如果我更改第一个文件中的代码,并且我不尝试分离 promise 链,如下所示:
query(){
let p = new Promise((resolve, reject) => {
resolve("Hello world")
}).then(data => {
console.log("Hello world a second time!");
}).then(data => {
console.log("Hello world a third time")
})
return p;
}
它工作正常,并打印:
Hello world a second time!
Hello world a third time
Hello world from the other file!
我不明白这种行为,我在想从 promise 定义中单独声明 then
块与在我声明 promise 时正确地进行 promise 链接是一回事,但显然不是像那样!
预先感谢您给我的答案。另外,如果你能给我一些关于如何正确编写这样的代码的建议,那就太好了。我的意思是,如果我编写使用 promise 的代码,我应该 return 给用户什么?另一个承诺?或者只是供他们使用的数据?我真的很想编写遵循 "standard" 做事方式的代码。
大家好!再次感谢。
而不是 return 在隔离版本中 p
... return p.then()
链。最后一个将被添加到该链的末尾,而不是创建两个不同的链
then()
return 任何 return 或 undefined
解决的新承诺,如果没有 return
const query = () => {
let p = new Promise((resolve, reject) => {
resolve("Hello world")
});
return p.then(data => {
// from `resolve()`
console.log('Then 1: ', data)
// return to next then()
return ("Hello world a second time!");
}).then(data => {
// from previous then()
console.log('Then 2: ', data)
// return to next then()
return ("Hello world a third time")
});
}
query().then(res => console.log('Final: ', res))
当您有一个 Promise 时,您可以将 任意数量 个 Promise 链接到它的 .then
上。例如
const p = Promise.resolve();
p.then(() => console.log('then 1');
p.then(() => console.log('then 2');
意味着 p
有 两个 承诺,当它解决时从它分支: 1
和 2
(除了承诺p
本身)。
p
/ \
/ \
1 2
你在第一个代码中做了什么
let p = new Promise((resolve, reject) => {
resolve("Hello world")
});
p.then(data => {
console.log("second");
}).then(data => {
console.log("third")
})
return p;
就像
"Hello world" = <Promise you return>
|
|
|
second
|
|
|
third = <unused Promise expression that the then chain resolves to>
您有两个分支:您返回的 Promise 在 Hello world
运行时解析,而不是在 third
运行时解析。
另一方面,当您在 Promise 上多次调用 .then
时,整个表达式的计算结果为解析 的 Promise,当最后的 .then
运行时 :
let p = new Promise((resolve, reject) => {
resolve("Hello world")
}).then(data => {
console.log("Hello world a second time!");
}).then(data => {
console.log("Hello world a third time")
})
return p;
就像
"Hello world"
|
|
'Hello second'
|
|
'Hello third' = <Promise you return>
其中返回的 Promise 是 Hello third
运行后立即解决的 Promise。
我正在学习 Node.js 并尝试正确使用 mysql2 模块。因此,我最近开始研究承诺。
我正在写一种 "library",这样我就可以练习所有这些主题,而在这样做的同时,我遇到了一个我无法真正理解的承诺链问题。非常感谢任何帮助!
问题如下:
假设我有一个 query
函数来获取数据库、处理数据和 return 一个承诺,这样我就可以获取该数据并在其他文件中使用它。
现在,如果我这样写 query
函数:
query(){
let p = new Promise((resolve, reject) => {
resolve("Hello world")
});
p.then(data => {
console.log("Hello world a second time!");
}).then(data => {
console.log("Hello world a third time")
})
return p;
}
我尝试 "consume" 来自其他文件的承诺,如下所示:
DBObject.query().then((data) => {
console.log("Hello world from the other file!");
})
然后输出顺序错误,程序打印如下:
Hello world a second time!
Hello world from the other file!
Hello world a third time
另一方面,如果我更改第一个文件中的代码,并且我不尝试分离 promise 链,如下所示:
query(){
let p = new Promise((resolve, reject) => {
resolve("Hello world")
}).then(data => {
console.log("Hello world a second time!");
}).then(data => {
console.log("Hello world a third time")
})
return p;
}
它工作正常,并打印:
Hello world a second time!
Hello world a third time
Hello world from the other file!
我不明白这种行为,我在想从 promise 定义中单独声明 then
块与在我声明 promise 时正确地进行 promise 链接是一回事,但显然不是像那样!
预先感谢您给我的答案。另外,如果你能给我一些关于如何正确编写这样的代码的建议,那就太好了。我的意思是,如果我编写使用 promise 的代码,我应该 return 给用户什么?另一个承诺?或者只是供他们使用的数据?我真的很想编写遵循 "standard" 做事方式的代码。
大家好!再次感谢。
而不是 return 在隔离版本中 p
... return p.then()
链。最后一个将被添加到该链的末尾,而不是创建两个不同的链
then()
return 任何 return 或 undefined
解决的新承诺,如果没有 return
const query = () => {
let p = new Promise((resolve, reject) => {
resolve("Hello world")
});
return p.then(data => {
// from `resolve()`
console.log('Then 1: ', data)
// return to next then()
return ("Hello world a second time!");
}).then(data => {
// from previous then()
console.log('Then 2: ', data)
// return to next then()
return ("Hello world a third time")
});
}
query().then(res => console.log('Final: ', res))
当您有一个 Promise 时,您可以将 任意数量 个 Promise 链接到它的 .then
上。例如
const p = Promise.resolve();
p.then(() => console.log('then 1');
p.then(() => console.log('then 2');
意味着 p
有 两个 承诺,当它解决时从它分支: 1
和 2
(除了承诺p
本身)。
p
/ \
/ \
1 2
你在第一个代码中做了什么
let p = new Promise((resolve, reject) => {
resolve("Hello world")
});
p.then(data => {
console.log("second");
}).then(data => {
console.log("third")
})
return p;
就像
"Hello world" = <Promise you return>
|
|
|
second
|
|
|
third = <unused Promise expression that the then chain resolves to>
您有两个分支:您返回的 Promise 在 Hello world
运行时解析,而不是在 third
运行时解析。
另一方面,当您在 Promise 上多次调用 .then
时,整个表达式的计算结果为解析 的 Promise,当最后的 .then
运行时 :
let p = new Promise((resolve, reject) => {
resolve("Hello world")
}).then(data => {
console.log("Hello world a second time!");
}).then(data => {
console.log("Hello world a third time")
})
return p;
就像
"Hello world"
|
|
'Hello second'
|
|
'Hello third' = <Promise you return>
其中返回的 Promise 是 Hello third
运行后立即解决的 Promise。