来自早期承诺的控制台日志出现在来自最新承诺的控制台日志之后
Console log from earlier promise appears after console log from latest promise
下面不是我的确切代码,但我只是想概述一下结构。当我 运行 代码时,我得到控制台日志的序列是这样的:
- 'Done'
- json
我原以为这是相反的,因为为了让 function2 完成(并发送 'Done' 解析值),function3 必须先完成。
我想了解为什么它不能那样工作。
function1().then(() => {
return function2()
).then((message) => {
console.log(message)
})
function function2() {
return new Promise((resolve, reject) => {
fetch(url, {
method: 'get',
body: null,
headers: {
"Content-Type": "application/json; charset=UTF-8",
"Accept": "application/json; charset=UTF-8",
},
})
.then(res => res.json())
.then((json) => {
return function3(json)
})
resolve('Done')
})
}
function function3(json) {
console.log(json)
}
你在你的 fetch
完成之前打电话给 resolve
。
如果你把它移到另一个就可以了 then
:
// ...
.then(res => res.json())
.then((json) => {
return function3(json)
})
.then(() => {
resolve('Done')
})
但事实上,整个 new Promise
事情甚至都没有必要,因为 fetch
已经 returns 一个承诺!
// ...
function function2() {
return fetch(url, { // It's important to actually *return* the promise here!
method: 'get',
body: null,
headers: {
"Content-Type": "application/json; charset=UTF-8",
"Accept": "application/json; charset=UTF-8"
}
})
.then(res => res.json())
.then((json) => {
return function3(json)
})
.then(() => {
return 'Done'
})
}
这可以使用 async
/await
进一步简化:
// I moved this into a function because the global module-level code
// is not in an async context and hence can't use `await`.
async function main () {
await function1()
console.log(await function2())
}
async function function1 () {
// I don't know what this does, you didn't include it in your code snippet
}
async function function2 () {
const response = await fetch(url, {
method: 'get',
body: null,
headers: {
"Accept": "application/json; charset=UTF-8"
}
})
const json = await response.json()
await function3(json)
return 'Done'
}
// At the moment this wouldn't have to be async because you don't do anything
// asynchronous inside, but you had `return function3(json)` in the original code,
// so I assume it is *going* to be async later.
async function function3 (json) {
console.log(json)
}
// Don't forget to .catch any rejections here! Unhandled rejections are a pain!
main().catch(console.error)
(当我在那里时,我删除了 Content-Type
header,因为它对 GET
请求没有任何意义。)
在函数2中,调用了fetch,只有.then()链被暂停。下一个要阅读的 javascript 是解决承诺的 resolve() 。几秒钟后,承诺解决并继续沿着链向下到达功能 3,其中记录了 'Done'
您错过了一个事实,即 fetch 以异步方式工作并加载到回调队列,而 resolve here 以同步方式工作。因此,即使 fetch 在 resolve 之前完成,由于 javascript 循环,它仍然会在 resolve 之后执行。您需要在进一步的获取链中链接解析以实现所需的功能。
下面不是我的确切代码,但我只是想概述一下结构。当我 运行 代码时,我得到控制台日志的序列是这样的:
- 'Done'
- json
我原以为这是相反的,因为为了让 function2 完成(并发送 'Done' 解析值),function3 必须先完成。
我想了解为什么它不能那样工作。
function1().then(() => {
return function2()
).then((message) => {
console.log(message)
})
function function2() {
return new Promise((resolve, reject) => {
fetch(url, {
method: 'get',
body: null,
headers: {
"Content-Type": "application/json; charset=UTF-8",
"Accept": "application/json; charset=UTF-8",
},
})
.then(res => res.json())
.then((json) => {
return function3(json)
})
resolve('Done')
})
}
function function3(json) {
console.log(json)
}
你在你的 fetch
完成之前打电话给 resolve
。
如果你把它移到另一个就可以了 then
:
// ...
.then(res => res.json())
.then((json) => {
return function3(json)
})
.then(() => {
resolve('Done')
})
但事实上,整个 new Promise
事情甚至都没有必要,因为 fetch
已经 returns 一个承诺!
// ...
function function2() {
return fetch(url, { // It's important to actually *return* the promise here!
method: 'get',
body: null,
headers: {
"Content-Type": "application/json; charset=UTF-8",
"Accept": "application/json; charset=UTF-8"
}
})
.then(res => res.json())
.then((json) => {
return function3(json)
})
.then(() => {
return 'Done'
})
}
这可以使用 async
/await
进一步简化:
// I moved this into a function because the global module-level code
// is not in an async context and hence can't use `await`.
async function main () {
await function1()
console.log(await function2())
}
async function function1 () {
// I don't know what this does, you didn't include it in your code snippet
}
async function function2 () {
const response = await fetch(url, {
method: 'get',
body: null,
headers: {
"Accept": "application/json; charset=UTF-8"
}
})
const json = await response.json()
await function3(json)
return 'Done'
}
// At the moment this wouldn't have to be async because you don't do anything
// asynchronous inside, but you had `return function3(json)` in the original code,
// so I assume it is *going* to be async later.
async function function3 (json) {
console.log(json)
}
// Don't forget to .catch any rejections here! Unhandled rejections are a pain!
main().catch(console.error)
(当我在那里时,我删除了 Content-Type
header,因为它对 GET
请求没有任何意义。)
在函数2中,调用了fetch,只有.then()链被暂停。下一个要阅读的 javascript 是解决承诺的 resolve() 。几秒钟后,承诺解决并继续沿着链向下到达功能 3,其中记录了 'Done'
您错过了一个事实,即 fetch 以异步方式工作并加载到回调队列,而 resolve here 以同步方式工作。因此,即使 fetch 在 resolve 之前完成,由于 javascript 循环,它仍然会在 resolve 之后执行。您需要在进一步的获取链中链接解析以实现所需的功能。