【前端】ES6:Promise对象和Generator函数

文章目录

  • [1 Promise对象](#1 Promise对象)
    • [1.1 回调地狱](#1.1 回调地狱)
    • [1.2 Promise使用](#1.2 Promise使用)
    • [1.3 Promise对象的状态](#1.3 Promise对象的状态)
    • [1.4 Promise.all](#1.4 Promise.all)
    • [1.5 Promise.race](#1.5 Promise.race)
  • [2 Generator函数](#2 Generator函数)
    • [2.1 基本语法](#2.1 基本语法)
    • [2.2 异步流程](#2.2 异步流程)
      • [2.2.1 手动版本](#2.2.1 手动版本)
      • [2.2.2 自动版本](#2.2.2 自动版本)

1 Promise对象

Promise是异步编程的一种解决方案,比传统的解决方案回调函数,更合理和更强大。

ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象 。

  • 指定回调函数方式更灵活易懂。
  • 解决异步 回调地狱 的问题。

1.1 回调地狱

当一个回调函数嵌套一个回调函数的时候,就会出现一个嵌套结构,当嵌套的多了就会出现回调地狱的情况。

比如我们发送三个ajax请求:

  • 第一个正常发送。
  • 第二个请求需要第一个请求的结果中的某一个值作为参数。
  • 第三个请求需要第二个请求的结果中的某一个值作为参数。

回调地狱,其实就是回调函数嵌套过多导致的。

javascript 复制代码
ajax({
  url: '我是第一个请求',
  success (res) {
    // 现在发送第二个请求
    ajax({
      url: '我是第二个请求',
      data: { a: res.a, b: res.b },
      success (res2) {
        // 进行第三个请求
        ajax({
          url: '我是第三个请求',
          data: { a: res2.a, b: res2.b },
  		  success (res3) { 
            console.log(res3) 
          }
        })
      }
    })
  }
})

1.2 Promise使用

javascript 复制代码
new Promise(function (resolve, reject) {
  // resolve 表示成功的回调
  // reject 表示失败的回调
}).then(function (res) {
  // 成功的函数
}).catch(function (err) {
  // 失败的函数
})

1.3 Promise对象的状态

Promise 对象通过自身的状态,来控制异步操作。

Promise 实例具有三种状态。

  • 异步操作未完成(pending)
  • 异步操作成功(fulfilled)
  • 异步操作失败(rejected)

这三种的状态的变化途径只有两种。

  • 从"未完成"到"成功"
  • 从"未完成"到"失败"

一旦状态发生变化,就凝固了,不会再有新的状态变化。这也是Promise这个名字的由来,它的英语意思是"承诺",一旦承诺成效,就不得再改变了。这也意味着,Promise实例的状态变化只可能发生一次。

因此,Promise的最终结果只有两种。

  • 异步操作成功,Promise实例传回一个值(value),状态变为fulfilled。
  • 异步操作失败,Promise实例抛出一个错误(error),状态变为rejected。

1.4 Promise.all

Promise.all()方法用于将多个Promise实例,包装成一个新的Promise实例。

javascript 复制代码
const p = Promise.all([p1, p2, p3]);

p的状态由p1,p2,p3 决定,分成两种情况。

  • 只有p1p2p3的状态都变成fulfilledp的状态才会变成fulfilled,此时p1p2p3的返回值组成一个数组,传递给p的回调函数。
  • 只要p1p2p3之中有一个被rejectedp的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

1.5 Promise.race

Promise.race()方法同样是将多个Promise实例,包装成一个新的Promise实例。

javascript 复制代码
const p = Promise.race([p1, p2, p3]);

上面代码中,只要p1p2p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的Promise实例的返回值,就传递给p的回调函数。

2 Generator函数

Generator函数是ES6提供的一种异步编程解决方案。

Generator函数是一个状态机,封装了多个内部状态。

执行Generator函数会返回一个遍历器对象,也就是说,Generator函数除了状态机,还是一个遍历器对象生成函数。返回的遍历器对象,可以依次遍历Generator函数内部的每一个状态。

2.1 基本语法

js 复制代码
function *gen(){
    console.log(1)
    yield;
    console.log(2)
    yield;
    console.log(3)
}

let g = gen()
g.next()
g.next()
g.next()

yield(产出)表达式是暂停执行的标记,而next方法可以恢复执行。

js 复制代码
function *gen(){
    yield  1;
    yield  2;
}

let g = gen()
let res1 = g.next()
console.log(res1)
let res2 = g.next()
console.log(res2)
let res3 = g.next()
console.log(res3)
js 复制代码
function *gen(){
    let res1 = yield;
    console.log(res1)
    let res2 = yield;
    console.log(res2)
}

let g = gen()
g.next("data-1")
g.next("data-2")
g.next("data-3")
javascript 复制代码
function *gen(){
	let res1 = yield "aaa"//产出
    console.log("gen内部",res1)
	let res2 = yield "bbb"
	console.log("gen内部",res2)
}

let g = gen()
let res1 = g.next("传入-11111") // 第1次next(),到yield停,"aaa"赋值给res1
console.log(res1)               // 打印:aaa
let res2 = g.next("传入-22222") // 第2次next(),将"传入-22222"赋值给let res1 = yield "aaa"中的res1,打印:gen内部,传入-22222,到yield停,"bbb"赋值给res2
console.log(res2)               // 打印:bbb
let res3 = g.next("传入-33333") // 将"传入-33333"赋值给let res2 = yield "bbb"中的res2,打印:gen内部,传入-33333
console.log(res3)               // 打印:undefined

2.2 异步流程

2.2.1 手动版本

js 复制代码
function *gen(){
    let res1 = yield ajax("1.json")
    console.log(res1)
    let res2 = yield ajax("2.json")
    console.log(res2)
}

let g = gen()   

g.next().value.then(data=>{
    g.next(data).value.then(data=>{
        g.next(data)
    })
}) 

//async await 内置自动执行器

2.2.2 自动版本

js 复制代码
function* gen() {
    let res1 = yield ajax("1.json")
    console.log(res1)
    let res2 = yield ajax("2.json")
    console.log(res2)
}


function AutoRun(gen) {
    let g = gen();

    function next(data) {
        let res = g.next(data); // 第1次next()
        if(res.done) return 
        res.value.then(function (data) {
            next(data); // 第2次next()
        });
    }
    next();
}

AutoRun(gen);
相关推荐
Myli_ing3 分钟前
HTML的自动定义倒计时,这个配色存一下
前端·javascript·html
dr李四维20 分钟前
iOS构建版本以及Hbuilder打iOS的ipa包全流程
前端·笔记·ios·产品运营·产品经理·xcode
I_Am_Me_34 分钟前
【JavaEE进阶】 JavaScript
开发语言·javascript·ecmascript
雯0609~41 分钟前
网页F12:缓存的使用(设值、取值、删除)
前端·缓存
℘团子এ44 分钟前
vue3中如何上传文件到腾讯云的桶(cosbrowser)
前端·javascript·腾讯云
学习前端的小z1 小时前
【前端】深入理解 JavaScript 逻辑运算符的优先级与短路求值机制
开发语言·前端·javascript
前端百草阁1 小时前
【TS简单上手,快速入门教程】————适合零基础
javascript·typescript
彭世瑜1 小时前
ts: TypeScript跳过检查/忽略类型检查
前端·javascript·typescript
FØund4041 小时前
antd form.setFieldsValue问题总结
前端·react.js·typescript·html
Backstroke fish1 小时前
Token刷新机制
前端·javascript·vue.js·typescript·vue