JavaScript Promise:多.then分句对比单.then分句,为何单分句输出undefined?
问题:合并fetch的.then分句后输出undefined的原因
我搭建了一个测试用Node.js服务器,向http://localhost:3060/发送GET请求时,会返回JSON:{ "message" : "hello there" }。
基准代码(多.then分句,正常工作)
function footgun() { fetch('http://localhost:3060/') .then(res => res.json()) .then(json => json.message) .then(msg => console.log(msg)); }
该代码输出:hello there,符合预期。
我知道每个.then()都会返回Promise对象,觉得这种写法有性能浪费,就尝试把所有逻辑整合到单个.then分句中:
修改后的代码(单.then分句,输出undefined)
function footgun() { fetch('http://localhost:3060/') .then(res => { const json = res.json(); const msg = json.message; console.log(msg); }); }
但此时输出结果为undefined,请问为何单.then分句的写法无法正常工作?
原因分析与解决办法
问题根源
核心问题在于res.json()的返回值特性:
res.json()不会直接返回解析好的JSON对象,它返回的是一个Promise。这个Promise要等JSON解析完成后,才会把实际的JSON数据作为resolve结果传递出去。- 在你的单
.then代码里,你直接把res.json()返回的Promise对象赋值给了json,然后试图访问json.message。但Promise对象本身没有message属性,所以自然输出undefined。
而最初的多.then写法能正常工作,是因为第一个.then(res => res.json())会自动等待这个Promise完成,把解析后的JSON对象传递给下一个.then,后续操作都是基于真实的JSON数据执行的。
正确的单.then写法
如果要把逻辑整合到一个.then里,可以在内部处理res.json()的Promise:
function footgun() { fetch('http://localhost:3060/') .then(res => { res.json().then(json => { console.log(json.message); }); }); }
或者用更易读的async/await写法:
async function footgun() { const res = await fetch('http://localhost:3060/'); const json = await res.json(); console.log(json.message); }
内容的提问来源于stack exchange,提问作者Gene keto
相关产品推荐
相关产品推荐

