我需要编写一个函数,该函数进行两个链接的HTTP调用,并在第二个调用的结果可用时对结果进行操作。
我认为可行的方法是
function getdata() {
return fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(r => r.json())
.then(r => fetch(`https://jsonplaceholder.typicode.com/todos/2`)
.then(s => s.json())
)
}
let m = getdata()
m.then(x => console.log(JSON.stringify(x)))
这很好,控制台输出符合预期。
然后我将这个想法移植到我的实际呼叫中,主要区别在于HTTPS呼叫速度很慢。为了将实际错误映射到代码,请考虑上面代码的小变化(添加了一些日志记录)
function getdata() {
return fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(r => r.json())
.then(r => fetch(`https://jsonplaceholder.typicode.com/todos/2`)
.then(s => {
console.log(s)
s.json()
})
)
}
let m = getdata()
m.then(x => console.log(x))
控制台输出(根据我的实际代码)类似于
11:36:56.388 undefined
11:36:56.456 filter-sentinels.js:42 Response {type: "cors", url: …}
详细信息:
undefined
来自console.log(x)
console.log(s)
在第二行(第一行之后)似乎解决了Promise。这很正常,这就是诺言的目的。
我不理解的是为什么在承诺尚未解决的情况下执行.then()
中的m.then(x => console.log(x) ))
?
关于标题的注释:我真正想了解的是,我是否可以将正在生成的Promise(let m = ...
)视为同步的东西-从某种意义上说,我可以安全地将then()
应用于知道相关信息(返回HTTP调用)后,它将发生then()
中发生的事情。
答案 0 :(得分:3)
问题是,在已完成的fetch
中有一个没有与外部的s.json()
链接的承诺:
.then(s => {
console.log(s)
s.json() // <---- This is not being returned; the Promise chain will resolve to undefined
})
您只是声明 s.json()
承诺,但您没有返回它,也没有使用它,因此整个getdata()
Promise都解析为{{ 1}},一旦来自undefined
的回复回来。
返回最后一个嵌套的/totos/2
调用,它可以按预期工作:
.json()