ES6中的Generator函数和Promise

19 篇文章 0 订阅

一、Generator

是ES6提供的一种异步编程解决方案,语法不同于普通函数;简单的把Generator 理解为一个状态机,封装了多个内部状态。执行Generator 函数会返回一个迭代器对象,可以通过调用迭代器next依次遍历Generator函数内部的每一个状态。

(一)Gererator函数的特征:

1.function关键字和函数名之间有*号(可以紧跟function,也可以紧跟函数名,也可以在两者之间)

2.函数内部使用yield表达式

普通的函数

function test(){
    //想要Generato函数有返回值
     3行代码
    return 1
     3行代码
    return 2
    
     3行代码
    return 3
    3行代码
    return 4

Generator函数

function* test(){
    //想要Generato函数有返回值
    //Generator状态机管理
     3行代码
    yield 1
     3行代码
    yield 2
     3行代码
    yield 3
    3行代码
    yield 4
}
在普通函数中只要有return之后,后面的代码将不再执行,而Generator函数中提供了yield,每调用一次next()就执行一个yeild的状态,上一个yeild的结束是下一个yeild的开始。最后一个yeild可以换成return。

(二)Generator函数的创建

Generator函数返回的是一个可迭代对象,  调用next()方法会执行yiled的状态,一个yield就是一个状态  一个yield就是一个代码的节点。

<body>
  <!-- Generator函数返回一个迭代器对象  next()方法  会执行yiled的状态 
    一个Yield就是一个状态  一个yield就是一个代码节点
  -->

  <script>
    function* Generator () {
      // 内部使用yield表达式(不会像return一样阻止代码向下执行)
      yield '1我是第一个返回值状态  我被执行了'
      yield '2'
      yield '3'

    }
    let res = Generator() //返回值返回的是一个迭代器对象或者generator对象
    // console.log(res);
    for (let k of res) {
      console.log(k);
    }
    console.log(res);
    console.log(res.next());//调用一次next执行一个状态
    // console.log(res.next());//调用一次next执行一个状态
    // console.log(res.next());//调用一次next执行一个状态
  </script>
</body>

(三)模拟发起异步请求,拿第一个状态的返回结果再执行第二个状态 状态之间的数据传递通过next()

<script>
    function* Generator () {
      // 内部使用yield表达式
      log();
      let res = yield '1';
      // 返回值 对这个状态耳朵描述
      // 如果想要在第二个状态使用第一个状态的返回值
      // 直接使用是获取不到的
      console.log(res, '获取res');
      log();
      yield '2'
      log();
      yield '3'
    }
    let res = Generator()
    // 返回值 返回的是一个迭代器对象/generation对象
    res.next();//发起第一个状态的执行
    res.next(100);
    // 如果想要在第二个状态拿到第一个状态的返回值
    // 就需要在第二个状态执行的时候传递参数
    // 发起第二个状态的执行
    // 模拟异步请求
    function log () {
      for (let i = 1; i <= 10; i++) {
        console.log(i);
      }
    }

  </script>
<script>
    function* Generator () {
      let res = yield getData();
      console.log(res, '获取响应');
      yield '结束了'
    }
    let res = Generator()//返回值  返回的是一个迭代器对象/generator对象
    res.next();
    async function getData () {
      // 发起一个异步请求
      let result = await axios.get('https//....');
      // 应该在第一个状态的异步请求中发起第二段程序/第二个状态的执行
      // 上一个状态返回值作为下一个状态的入口
      // 第一个状态的方法里面发起第二个状态的执行
      res.next(result);
    }
  </script>

二、Promise

是一种异步编程解决方案,Promise是一个容器,保存着将来才会执行的代码;从语法角度来说Promise是一个对象,可以用来获取异步操作的消息。异步操作,同步解决,避免了层层嵌套的回调函数,可以链式调用降低了操作难度 .

1.实例化

Promise构造函数接收一个函数作为参数,也就是回调函数;该函数的两个参数分别是resolve和reject。resolve作为成功的回调函数,reject作为失败的回调函数。Promise对象代表一个异步操作有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。最后返回resolved(已定型)结果。

2.实例方法

定义在Promise.prototype中的方法,通过Promise实例可以直接调用
    then(res=>{}) 状态由pending变为fulfilled的时候也就是异步操作成功之后执行该回调函数
        参数:回调函数,回调函数的参数为resolve函数传递过来的值
        返回值:返回一个新的Promise实例对象,因此可以使用链式调用
    catch(err=>{}) 由pending变为rejected的时候执行该回调函数也就是异步失败之后执行该回调函数
        参数:回调函数,回调函数的参数为reject函数传递过来的值
        返回值:返回一个新的Promise实例对象,因此可以使用链式调用
    finally()无论异步操作执行成功失败与否,都会执行该回调
        参数:回调函数
        返回值:返回一个新的Promise实例对象

 <script>
    // 声明一个promise对象
    // Promise函数:参数  回调函数(resolve,reject)
    let promise = new Promise((resolve, reject) => {
      // resolve代表的是成功回调函数
      // reject 代表的是失败回调函数
      // 模拟异步请求
      if (3 > 2) {
        resolve('success')
      } else {
        reject('error')
      }
    })
    console.log(promise, '承诺对象');
    // resolve reject由谁提供
    // resolve由then方法提供  reject由catch提供

    // then可以有两个参数
    // promise.then(res=>{
    //   console.log(res,'请求成功');
    // },err=>{
    //   console.log(err,'请求失败');
    // })
    promise.then(
      // 执行的是成功的回调函数
      (res) => {
        console.log(res, '请求成功');
      }
    ).catch(
      // 执行的是失败的回调函数
      (err) => {
        console.log(err, '请求失败');
      }
    ).finally(() => {
      console.log('最终执行');
    })
    // finally  loading
    // 这个项目  数据一直不回来  loading=false
    // Promise 做什么?  封装AJAX
  </script>

3.静态方法:只能由构造函数本身去调用

定义在Promise方法中,通过Promise可以直接调用

<body>
	<script>
		// 创建多个承诺对象得实例
		// let p1=new Promise(()=>{
		// 	// 发异步请求 
		// 四步走
		// 	resolve();//请求成功
		// 	reject();//请求失败
		// })

		function promise (method, url, obj) {
			return new Promise((reslove, reject) => {
				// 封装ajax
				let xhr = new XMLHttpRequest();
				// 打开一个连接
				xhr.open(method, url);
				// 发送请求
				xhr.send();
				// 接收响应
				xhr.onreadystatechange = function () {
					if (xhr.readyState === 4) {
						if (xhr.status === 200) {
							// 代表请求成功 
							reslove(xhr.responseText)
						} else {
							// 代表请求失败
							reject(xhr.responseText)
						}
					}
				}
			})
		}
		let p1 = promise('get', 'http://121.199.0.35:8887/index/carousel/findAll');
		let p2 = promise('get', 'http://121.199.0.35:8888/index/article/findCategoryArticles');

		// 静态方法 只能由构造函数本身去调用 Promise
		// 实例全部成功返回一个承诺对象 
		// 参数 数组[存放多个promise实例对象]
		// 返回值 返回一个promise实例
		// let res=Promise.all([p1,p2]);
		// 任意一个实例状态成功返回成功得实例
		// let res=Promise.any([p1,p2]);
		// race 赛跑 返回请求先成功得实例对象
		// let res=Promise.race([p1,p2]);

		// let res = Promise.allSettled([p1, p2]);
		// 区别?
		// 1.返回得处理格式问题 array:[{},{}]
		// all 实例 pendding
		// console.log(res);
		// res.then(res => {
		// 	console.log(res);
		// })
		// console.log(res);
		// res.then(res => {
		// 	console.log(res, '请求成功');
		// })
		// console.log(p1, p2);
		p1.then(res => {
			console.log(res, '获取响应1');
		});
		// p2.then(res => {
		// 	console.log(res, '获取响应2');
		// });
	</script>
</body>

Promise.all([p1,p2])

参数:数组,数组中的元素为Promise实例

返回值:Promise实例,当p1 p2都请求成功之后该实例的状态才是fulfilled,此时p1和p2的返回值

组成一个数组,传递给该实例的回调函数,只要p1,p2的返回值有一个变为rejected,该实例状态为rejected;

Promise.race([p1,p2])赛跑返回先请求成功的实例

参数:数组  数组中的元素为Promise实例

返回值:哪个先请求到就返回哪个请求的结果

Promise.any([p1,p2])

参数:数组  数组中的元素为Promise实例

返回值:Promise实例,只要p1,p2状态有一个变为fulfilled,该实例的状态为fulfilled;p1,p2状态都变为erjected,该实例状态才为rejected

Promise.allSettled([p1, p2])

参数:数组  数组中的元素为Promise实例

返回值:不管请求有没有成功此方法都会对这两个实例进行操作,但最终展示的是请求成功的数据

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值