Promise的创建是否同步?

时间:2019-04-04 10:32:49

标签: javascript promise

我需要编写一个函数,该函数进行两个链接的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()中发生的事情。

1 个答案:

答案 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()