如何在Deno中转换Fetch返回的JSON流并生成新响应?
问题:Deno中如何将ReadableStream转为JSON并修改后返回响应体?
我是Deno新手,现有以下代码:
const getCOP = async()=>{ const resp = await fetch("....", { headers: { accept: "application/json", apiKey }, }); return await resp.body; } let resp = {} return new Response(resp.body, { status: resp.status, headers: { "content-type": "application/json", }, }); resp.body = await getCOP(); resp.status = 200;
接口返回的原始JSON结构是:
{ "success": true, "timestamp": 1675621083, "base": "COP", "date": "2023-02-05", "rates": { "EUR": 0.000199, "GBP": 0.000179, "USD": 0.000216 } }
我想要实现这样的逻辑:
return { rate : resp.body.rates, copPerDollar : 1 / resp.body.rates.USD }
但现在resp.body是ReadableStream,不是JSON对象,请问怎么把流转成JSON,修改后再作为响应体返回?
解决方案
1. 先修正代码逻辑顺序
你原来的代码把return new Response()写在了resp.body = await getCOP()前面,这会导致还没获取数据就先返回了,完全逻辑颠倒,得先调整执行顺序。
2. 将ReadableStream转为JSON对象
不要直接返回resp.body,用Response.json()方法,它会自动读取流内容并解析成JSON对象,这是最简便的方式。
3. 处理数据并返回响应
拿到解析后的JSON后,按照需求生成新的数据结构,再把这个结构传给new Response(),Deno会自动帮你把对象序列化为JSON并设置正确的Content-Type头(手动设置也没问题)。
修改后的完整代码:
const getCOP = async()=>{ const resp = await fetch("....", { headers: { accept: "application/json", apiKey }, }); // 用json()解析流为JSON对象,代替返回resp.body return await resp.json(); } // 先获取并解析数据 const copData = await getCOP(); // 生成想要的结构 const processedData = { rate: copData.rates, copPerDollar: 1 / copData.rates.USD }; // 返回处理后的响应 return new Response(processedData, { status: 200, headers: { "content-type": "application/json", }, });
补充:手动处理流的方式
如果因为特殊需求必须手动处理ReadableStream,可以用TextDecoder读取流内容后再解析:
const getCOP = async()=>{ const resp = await fetch("....", { headers: { accept: "application/json", apiKey }, }); // 手动读取流为字符串 const text = await resp.text(); // 解析为JSON对象 return JSON.parse(text); }
不过resp.json()是更简洁的内置方法,优先用这个即可。
内容的提问来源于stack exchange,提问作者Jackie
相关产品推荐
相关产品推荐

