使用fetch和await打印文本:为何async函数内需多个await?
关于async函数中多个await的疑问
首先得搞清楚async/await的本质:async函数本身会返回一个Promise,而await的作用是暂停当前async函数的执行,直到后面的Promise状态变为resolved(完成),然后拿到Promise的结果再继续往下走。
那为什么需要多个await呢?举个最常见的场景:
- 如果你需要先发起第一个请求(比如获取某个资源的ID),然后用这个ID作为参数发起第二个请求(比如获取该资源的详情),这两个请求是顺序依赖的——第二个请求必须等第一个请求完成拿到结果才能发起。这时候你就需要在每个异步操作前加
await,不然代码会“不等第一个请求完成就直接跑第二个”,拿不到正确的参数,结果肯定不对。
比如:
async function fetchData() { // 第一个请求必须await,不然resourceId会是Promise对象而不是实际ID const resourceResponse = await fetch('/api/resources'); const resourceId = await resourceResponse.json(); // 第二个请求依赖第一个的结果,所以也要await const detailResponse = await fetch(`/api/resources/${resourceId}`); const detail = await detailResponse.json(); console.log(detail); }
当然,如果你的多个异步操作是并行无关的(比如同时请求两个不相关的接口),其实不用挨个await,可以用Promise.all来同时发起,效率更高:
async function fetchParallel() { const [res1, res2] = await Promise.all([ fetch('/api/data1'), fetch('/api/data2') ]); const data1 = await res1.json(); const data2 = await res2.json(); }
简单说:多个await的核心原因是异步操作之间有依赖关系,或者你需要按顺序获取每个异步操作的结果。
React Native中使用fetch做网络爬虫的代码解析
先看你这段fetch配置,整体逻辑是没问题的,我来拆解下每个配置的作用和需要注意的点:
const response = await fetch(url, { body : post_data ? post_data : undefined, // must match 'Content-Type' header cache : 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached headers : headers, method : post_data ? 'POST' : 'GET', // *GET, POST, PUT, DELETE, etc. redirect : redirect ? 'follow' : 'manual', // *manual, follow, error. TODO: is manual the right keyword? referrer : 'no-referrer', // *client... });
- body配置:这个逻辑很合理——POST请求传body,GET请求不传(设为undefined)。但要注意:如果post_data是JSON格式,你需要在headers里设置
Content-Type: application/json,同时把body转成字符串:body: JSON.stringify(post_data),不然服务器可能解析不了你的请求。 - cache: 'no-cache':这个设置是对的,爬虫场景下我们不需要缓存,每次都获取最新的页面内容,避免拿到旧数据。
- headers:这里你没给出具体的headers内容,但爬虫时一定要设置合理的
User-Agent(模拟浏览器的UA,比如Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36),不然很多网站会识别出你是爬虫直接拒绝请求。另外如果是POST请求,一定要保证Content-Type和body格式匹配。 - method自动切换:根据是否有post_data来选GET/POST,这个逻辑没问题,符合HTTP请求的常规用法。
- redirect参数:关于你问的
manual是不是正确的关键字——要看你的需求:- 如果选
follow:fetch会自动跟随服务器的重定向(比如301/302跳转),最终返回的是重定向后的页面内容。 - 如果选
manual:fetch不会自动跳转,你需要通过response.redirected判断是否发生了重定向,然后自己处理response.url拿到跳转后的地址。
如果你只是想爬取目标页面的内容,follow更省心;如果需要追踪重定向路径,那manual是合适的。
- 如果选
- referrer: 'no-referrer':这个设置很好,爬虫时不发送referrer头,可以降低被网站识别为爬虫的概率。
最后给你几个React Native爬虫的额外建议:
- HTML解析:React Native没有浏览器的DOM API,所以爬取到HTML后,需要用第三方库(比如
cheerio)来解析和提取内容,记得先安装依赖:npm install cheerio。 - 反爬应对:除了设置UA,还可以适当添加请求间隔,避免短时间内发起大量请求被封IP;有些网站需要Cookie,你可以用
AsyncStorage来保存和复用Cookie。 - 异步控制:如果要爬多个页面,不要用普通的for循环直接await(会串行很慢),可以用
Promise.all控制并发数,比如每次同时爬3-5个页面,平衡效率和被封风险。
内容的提问来源于stack exchange,提问作者user6791424
相关产品推荐
相关产品推荐

