目录
Generator
如何创建Generator函数 ?
模拟发起异步请求
Promise
实例化
实例方法
工厂函数
静态方法
Promise.all([p1,p2,....])
Promise.race([p1,p2,....])
Promise.any([p1,p2,....])
Promise.allSettled([p1,p2,....])
Generator
Generator是ES6提供的一种异步编程解决方案,语法不同于普通函数;简单的把Generator 理解为一个状态机,封装了多个内部状态。执行Generator 函数会返回一个迭代器对象,可以通过调用迭代器next依次遍历Generator函数内部的每一个状态。
如何创建Generator函数 ?
每个状态之间都是独立的
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>/*** generator 函数 也是一种异步编程的解决方案 理解为状态机 内部封装多个状态* 调用generator 函数返回值是迭代器对象 每调用一次迭代器next方法 就会执行一个状态* 特征:* 1.function 和函数名之间使用* 靠前靠后不靠都可以* 2.返回一个迭代器对象 并且内部状态使用yiled表达式* * generator函数内部使用yield表达式 一个yield就是一个状态 一个yield就是一个代码节点通过迭代器对象的next方法控制的代码的向下执行。*/function * generator(){yield '1';yield '2';yield '3';}let res = generator();console.log(res.next());for(let key of res){console.log(key);}</script>
</body>
</html>
因为return会阻止后面的代码运行,所以 Generator提供了yield,yiled也是返回值,但是执行一次状态停在了第一个yield ,依次执行next方法,执行下一个yield状态。代码分段执行,一个yield分一段。上一个yield结束是下个状态的开始,下一个状态的结束再执行下一个yield。yield后面的是返回值。最后一个yield可以return返回。
模拟发起异步请求
拿到第一个状态的返回结果再执行第二个状态,状态之间数据传递通过next
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>/*** 想要在第二个状态执行的时候调用第一个状态的返回值 * 一个yield就是一个状态 一个yield就是一个代码运行节点 * 迭代器对象每次调用next只会执行一个状态* 迭代器对象调用next方法 执行第一个状态产生返回值 在第二个状态中是接收不到 * 可以在第二个状态中传递参数 返回值接收的就是什么参数 */function* generator(){// 发送一个请求 log();let res = yield '1';console.log(res,'第一个状态返回值');yield '2';}let res = generator();// 发起第一个状态的执行res.next();// 发起第二个状态的执行// 如果想要在第二个状态中获取第一个状态返回值 需要在第二段状态执行的时候传递参数res.next(100);// 模拟异步请求function log(){for(let i=0;i<=10;i++){console.log(i)}}</script>
</body>
</html>
如果想要实现数据传递 需要发起第二段程序执行 拿上一个状态得返回值作为下一个状态得入口
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="https://cdn.bootcdn.net/ajax/libs/axios/1.3.6/axios.js"></script>
</head>
<body><script>function *generator(){// 每一个代码节点发起异步请求 let res = yield getData();console.log(res,'第一个异步请求的返回值');yield '结束了';}let res = generator();res.next();// 封装一个异步函数async function getData(){let result = await axios.get('http://121.199.0.35:8888/index/carousel/findAll');// result 异步请求的返回值 后端返回的数据 result.dataconsole.log(result,'响应数据');// 在第一个状态的异步函数中发起第二段状态执行 并且把第一个状态产生返回值当做下一个状态的入口res.next(result.data);}</script>
</body>
</html>
Promise
Promise是一种异步编程解决方案,Promise是一个容器,保存着将来才会执行的代码;从语法角度来说Promise是一个对象,可以用来获取异步操作的消息。异步操作,同步解决,避免了层层嵌套的回调函数,可以链式调用降低了操作难度。
实例化
Promise构造函数接收一个函数作为参数,也就是回调函数;
该函数的两个参数分别是resolve和reject。resolve作为成功的回调函数,reject作为失败的回调函数。
Promise对象代表一个异步操作有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。最后返回resolved(已定型)结果。
实例方法
定义在Promise.prototype中的方法,通过Promise实例可以直接调用
then(res=>{}) 状态由pending变为fulfilled的时候也就是异步操作成功之后执行该回调函数
参数:回调函数,回调函数的参数为resolve函数传递过来的值
返回值:返回一个新的Promise实例对象,因此可以使用链式调用
catch(err=>{}) 由pending变为rejected的时候执行该回调函数也就是异步失败之后执行该回调函数
参数:回调函数,回调函数的参数为reject函数传递过来的值
返回值:返回一个新的Promise实例对象,因此可以使用链式调用
finally()无论异步操作执行成功失败与否,都会执行该回调
参数:回调函数
返回值:返回一个新的Promise实例对象
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=s, initial-scale=1.0"><title>Document</title>
</head>
<body><script>// 创建promise实例对象 参数 回调函数let promise = new Promise((resolve,reject)=>{/*** resolve 是成功的回调函数* reject 是失败的回调函数* 不发送请求 此时promise实例状态pending进行中*/// 模拟发送异步请求if(3<2){// let res = await axios.get();resolve('发送成功');}else{reject('发送失败')}});// console.log(promise);/*** promise实例状态为fullfilled走then回调* promise实例状态为rejected走catch回调*/promise.then((res)=>{console.log(res);}).catch((error)=>{console.log(error);}).finally(()=>{console.log('最终状态');})/*** then方法提供了两个回调函数 * 第一个回调函数是成功的回调 第二个回调函数是失败的回调 * resolve reject*/promise.then((res)=>{console.log(res);},(error)=>{console.log(error);})</script>
</body>
</html>
考虑到需要创建多个promise实例对象 这些对象封装ajax请求
使用工厂函数创建promise实例对象
工厂函数
在下面静态方法的代码中
静态方法
Promise.all([p1,p2,....])
参数:数组 [多个promise实例] 返回值:promise实例 实例状态
每一个请求实例为fullfilled,才是fullfilled。否则是rejected
Promise.race([p1,p2,....])
参数:数组 [多个promise实例] 返回值:返回先请求成功的实例 返回的也是promise实例对象
Promise.any([p1,p2,....])
参数:数组 [多个promise实例] 返回值:返回任意一个成功的实例
Promise.allSettled([p1,p2,....])
参数:数组 [多个promise实例] 返回值:promise实例
每一个请求实例为rejected,才是rejected。否则是fullfilled
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><script>function promise(method, url) {return new Promise((resolve, reject) => {// 创建一个请求实例let xhr = new XMLHttpRequest();// 打开链接xhr.open(method, url);// 发送请求xhr.send();// 接收响应xhr.onreadystatechange = function () {if (xhr.readyState === 4) {if (xhr.status === 200) {resolve(JSON.parse(xhr.response));} else {reject('接收失败');}}}});}let p1 = promise('get', 'http://121.199.0.35:8888/index/category/findAll');let p2 = promise('get', 'http://121.199.0.35:8887/index/carousel/findAll');// p1.then((res) => {// console.log(res, 'res接收成功');// }).catch((error) => {// console.log(error, '出现错误');// })// p2.then((res) => {// console.log(res, 'res接收成功');// }).catch((error) => {// console.log(error, '出现错误');// })// 静态方法 同时发送多个请求// Promise.all([p1,p2,....]) 参数:数组 [多个promise实例] 返回值:promise实例 实例状态// 每一个请求实例为fullfilled,才是fullfilled。否则是rejectedlet res = Promise.all([p1,p2]);// Promise.race([p1,p2,....]) 参数:数组 [多个promise实例] 返回值:返回先请求成功的实例 返回的也是promise实例对象// let res = Promise.race([p1,p2]);// Promise.any([p1,p2,....]) 参数:数组 [多个promise实例] 返回值:返回任意一个成功的实例// let res = Promise.any([p1,p2]);// Promise.allSettled([p1,p2,....]) 参数:数组 [多个promise实例] 返回值:promise实例// 每一个请求实例为rejected,才是rejected。否则是fullfilled// let res = Promise.allSettled([p1,p2])console.log(res); //promise实例 实例状态 res.then((res)=>{console.log(res,'all方法res接收的是数组');}).catch((error)=>{console.log(error);})</script>
</body></html>