承诺不如预期 误会?
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,因此您需要等待它,方法是执行您在第二个示例中所做的操作,或者使用 async
和 await
:
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)
输出:
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,因此您需要等待它,方法是执行您在第二个示例中所做的操作,或者使用 async
和 await
:
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)
输出: