承诺不如预期 误会?

promise not work as expected misunderstanding?

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?

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

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

js fiddle: https://jsfiddle.net/hy15ve68/

演示如何从 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 的正确方法。

如您所见,我们 return return 由 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)

输出: