JS/异步-promise和fetch API

什么是异步

在单线处理的命令逻辑中,将耗时较长的程序从queue里拎出来,延迟?时间后,再callback回执行队列里,让该程序的执行不影响其他线性运行的程序

异步流程

1. 拎出需要异步的命令,延长xx时间setTimeOut…

setTimeOut(具体执行语句,延长时间)

2.1 执行异步请求->单个请求

如使用XMLHttp, Promise, fetch API。此处以fetch API为例。

1. 向目标server发出HTTP request,要求返回一个promise

fetch方法有两个参数,第一个是target url,第二个是针对HTTP request配置对象的不同属性可以调用的不同方法

method: 表示 HTTP 请求的方法,可以是 ‘GET’、‘POST’、‘PUT’ 等。默认值是 ‘GET’。
headers: 包含请求头的对象,可以设置各种请求头,如 ‘Content-Type’、‘Authorization’ 等。
body: 包含请求主体的内容,通常用于 POST 请求。可以是一个字符串、一个 FormData 对象,或者一个 URLSearchParams 对象等。
mode: 表示请求的模式,例如 ‘cors’、‘no-cors’、‘same-origin’ 等。
cache: 表示请求的缓存模式,如 ‘default’、‘no-store’、‘reload’ 等。
credentials: 表示是否发送凭据,如 cookies。可以是 ‘same-origin’、‘include’、‘omit’。
redirect: 表示遇到重定向时要采取的操作,如 ‘follow’、‘error’、‘manual’。
referrer: 表示请求的 referrer,可以是 ‘no-referrer’、‘client’、URL 等。
integrity: 包含请求的子资源完整性的字符串,用于校验文件完整性。

fetch('url',{
	method:'GET'	
})
2. 获得HTTP response,从中提取想要的属性

此时获得的(response)是整个HTTP响应,包括.status, .statusText, .json, .headers, .url等

  • .status: 状态码,如200表示正常
  • .json: json data,通过.json()来获取

此处以获取json data为例,此时server返回两种情况:1.有error 2.正常

fetch('url').then(response =>{
	if(!response.ok){ //1.有error,throw之
		throw Error('could not fetch the data for that resource');
	}return response.json(); //2.正常return json data
})
3. 对获取的data分为两种情况:reject/resolve
- resolve: 处理data
- reject: catch error
fetch('url')
	.then(response =>{
	return response.json();
	})
	.then(data =>{
	//execute data...
	})
	.catch(error(err=>{
	//catch error...
	err.message...
	})

2.2 执行异步请求->单个请求->需要取消异步请求

1. 设置需要取消异步请求的条件

使用 useEffect(func, conditions) ,令监测到conditions情况变化,或组件被激活卸载时,就执行函数func
示例:url变化或组件被卸载时激活 useEffect(func …,[url])

2. 创建一个AbortController控制器

const abortCont = new AbortController();

3. 让AbortController和下文的fetch异步操作相关联

AbortSignal 传给 fetch:fetch(url, { signal: abortCont.signal })

4. 在fun中返回一个清理函数

return () => abortCont.abort()
- 该函数执行场景:当组件要被卸载时 or 下一次url变化时
- 该函数执行用途:中止用AbortController关联的对应fetch异步操作,避免出现上述情况后仍然在进行异步

useEffect(() => {
	//2.创建一个AbortController控制器
	const abortCont = new AbortController();
    setTimeout(() => {
     //3.AbortSignal 传给 fetch,让AbortController和fetch异步操作相关联
      fetch(url, { signal: abortCont.signal })
      .then// ... (省略了一些代码)
     },1000);
    
    //3.返回一个清理函数 
    return () => abortCont.abort();
    
}, [url]); //1.设置需要取消异步请求的条件

3. 执行异步请求->多个请求

关于async和await:
  • async:声明此函数为异步函数,并回返回一个promise对象(两种情况:resolve/reject)
  • await:暂停函数执行,等待promise解决
  1. 设定发起单个异步请求的方法 const fetchData
  2. 批量处理所有的异步请求const func。用promise.all等待所有请求处理好后返回再return result
  3. 执行所有请求的数据处理。func().then.catch
//设定单个异步请求的发起
const fetchData = async (url) => {
    const response = await fetch(url);
    const data = await response.json();
    return data;
};

const func = async () => {
    const urls = ['url1', 'url2', 'url3']; // 替换为实际的URL数组
    const promises = urls.map(url => fetchData(url));
    try {
        const results = await Promise.all(promises);
        return results;
    } catch (error) {
        console.error('An error occurred:', error);
        throw error;
    }
};

func().then(data => {
    //execute data
}).catch(error => {
    //catch error
});

具体示例

import { useState, useEffect } from "react";

const useFetch = (url) => {
  // 设定data,pending和error三种状态
  const [data, setData] = useState(null);
  const [isPending, setIsPending] = useState(true);
  const [error, setError] = useState(null);

  //异步的两种情况:正常异步,需要中止异步
  useEffect(() => {
    const abortCont = new AbortController();

    setTimeout(() => {
      //中止异步:把AbortController连接到这个fetch上,好监测useEffect的url发生变动的情况从而执行abortCont.abort()中止异步
      fetch(url, { signal: abortCont.signal })
        // 正常异步:这一步return json格式的数据
        .then((res) => {
          //对返回的HTTP对象分两种情况:reject和resolve,如果reject,则throw error,反之return json data
          if (!res.ok) {
            throw Error("could not fetch the data for that resource");
          } else {
            return res.json();
          }
        })
        //这一步接收res.json,并对data执行操作:改变三个状态值
        .then((data) => {
          setIsPending(false);
          setData(data);
          setError(null);
        })
        //这一步对throw出来的error进行处理
        .catch((err) => {
          if (err.name === "AbortError") {
            console.log("fetch aborted");
          } else {
            setIsPending(false);
            setError(err.message);
          }
        });
    }, 1000);

    //若触发[url],则执行func->return abortCont.abort()
    return () => abortCont.abort();
  }, [url]);

  //最后对之前设置的三个状态数据都return
  return { data, isPending, error };
};

export default useFetch;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值