【问题标题】:promise not work as expected misunderstanding?承诺不按预期工作的误解?
【发布时间】:2022-01-22 06:53:55
【问题描述】:
fetch("https://jsonplaceholder.typicode.com/posts").then(
  (response) => {
    console.log(response.json()); //why the data not logged and promise is logged 
  }
);
but work if i writte 
let response = fetch("https://jsonplaceholder.typicode.com/posts")
  .then((response) => response.json())
  .then((data) => console.log(data));

为什么没有记录数据而第一个代码中记录了promise?

【问题讨论】:

  • 将承诺返回给 .then 继续承诺链。一旦返回到前一个的承诺解决,下一个 .then 就会被调用。通过跳过第二个 .then,您反而记录了您仍需要等待的未解决的承诺。

标签: javascript json promise fetch-api


【解决方案1】:

response.json() 正在返回一个 Promise,因此您需要等待它,方法是执行您在第二个示例中所做的操作,或者使用 asyncawait

fetch("https://jsonplaceholder.typicode.com/posts").then(
  async (response) => {
    console.log(await response.json());
  }
);

js 小提琴:https://jsfiddle.net/hy15ve68/

【讨论】:

  • 上帝保佑你,谢谢
  • .then(async () => {}) 是一种反模式
【解决方案2】:

用于演示如何从 Promise 中获取数据(不要这样做):

fetch("https://jsonplaceholder.typicode.com/posts").then(
  (response) => {
    // response.json() returns a Promise which we can call
    // .then() on.
    response.json().then(console.log)
  }
);

第二个代码实际上是以下代码的缩写:

let response = fetch("https://jsonplaceholder.typicode.com/posts")
  .then((response) => {
    return response.json()
  })
  // .then() refers to the promise returned by response.json()
  .then((data) => {
    return console.log(data)
  });

这是链接 Promise 的正确方式。

如你所见,我们返回response.json()返回的Promise,然后调用.then()

链接 Promise 的好处是同步值(如数字、字符串等)被包装在 Promise 中,因此您仍然可以在其上调用 .then()

let dummy_promise = (new Promise(resolve => {
    resolve(1)
}))

dummy_promise.then(value => {
    console.log("im expecting 1", value)

    return 2;
})
.then(value => {
    console.log("im expecting 2", value)

    return 3;
})
.then(value => {
    console.log("im expecting 3", value)
})
.then(value => {
    console.log("im expecting undefined because we haven't returned anything in the previous .then() block!", value)
})

一点背景资料:

你不能期望 Promise 的结果立即可用。

这就是您使用.then() 的原因 - 这是一种表达“当值可用时调用此函数”的方式。

当您console.log(response.json()) 时,您会得到 Promise 对象,但不是已解析的值。

注意:即使 Promise 本身已解决,response.json() 也会继续为您提供 Promise 对象本身。

您仍然可以在其上调用.then(),您的函数将使用解析后的值调用。

我希望这个小例子能说明我的意思:

// returns a Promise that gets resolved to "hello!" after
// 100 ms (milliseconds)
function something() {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve("hello!")
        }, 100)
    })
}

// call something() and store the promise in promise_object
let promise_object = something()

console.log("Installing .then() handlers")

// call console.log twice after promise is resolved
// (means they will be called in about 100ms - when the promise is resolved)
promise_object.then(console.log)
promise_object.then(console.log)

console.log("Installed .then() handlers")

// wait for 1 second, then print promise_object
setTimeout(() => {
    console.log("1 second has passed")

    // at this point the promise returned by something() surely must be 
    // resolved
    console.log(promise_object) // Still prints Promise {} and not "hello!" - that's intended behavior

    // gets called without delay because promise is already resolved!
    promise_object.then(console.log)
}, 1000)

输出:

【讨论】:

  • .then 在 .then 中似乎也是一种反模式,但我并不完全精通什么是反模式,什么不是反模式是。
  • 这就是为什么我以“这只是为了演示”开头的原因,如果您继续阅读,您会看到我展示了正确的做法。
猜你喜欢
  • 1970-01-01
  • 2018-09-19
  • 1970-01-01
  • 2019-02-05
  • 2019-12-03
  • 2019-01-19
  • 1970-01-01
  • 1970-01-01
  • 2022-01-17
相关资源
最近更新 更多