JavaScript ES(6-11)基础语法系列(6)

Promise对异步状态进行管理

Promise是一种异步任务顺序执行的新方法,为了解决callback问题。对异步状态进行管理。

基础语法  

 var promise = () => {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log("我叫张晓龙");
          resolve()
        }, 3000)
      })
    }
    promise().then(() => {
      console.log("好的知道了")
    })

Promise一共有三种状态,且成功和失败的状态时不可逆的

new Promise()会立即执行,所以一般在使用new Promise执行函数时,需要放到一个函数中去,并return出来,这样才能更好的执行。

new Promise()共有两个参数,一个是resolve,是函数体内代码成功执行后执行执行的回调函数。另一个是reject,是函数体中的代码,执行失败之后执行的回调函数。

成功的回调和失败回调有两种执行方式:

  1. 使用.then(successBack,failBack)    

promise().then(
      () => { console.log("好的知道了") }, () => { console.log("听不到你说啥"); }
    )
  1. 使用.cath

   promise().then(() => {
      console.log("好的知道了")
    }).catch(() => {
      console.log("听不到你说啥");
    })

Promise的使用场景

由于Promise的出现是为了解决callback问题的,而常见的需要异步任务顺序执行的操作就是,ajax操作。

Promise的静态方法

   
 let foo = res => {
      if (res) {
        return new Promise(resolve => {
          resolve('成功了~~~')
        })
      } else {
        return Promise.reject("失败了~~~")
      }
    }
    foo(false).then(res => { console.log(res) }).catch(res => { console.log(res) })

Promise.all()和Promise.race()  

 // Promise.all()和Promise.race()
    let p1 = new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve('p1成功了')
      }, 1000)
    })
    let p2 = new Promise((resolve, reject) => {
      setTimeout(() => {
        reject('p2失败了')
      }, 2000)
    })
    let p3 = new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve('p3成功了')
      }, 3000)
    })
    // Promise.all([p1, p2, p3]).then(res => {
    //   console.log(res);
    // }).catch(res => {
    //   console.log(res);
    // })
    Promise.race([p1, p2, p3]).then(res => {
      console.log(res);
    }).catch(res => {
      console.log(res);
    })
    // Promise.all()只有所有的都成功才会返回成功,只要有一个不成功,就返回不成功的那个promise
    // Promise.race()会返回最先接收到的结果,先接收到成功的就代表成功了,先接收到失败的就代表失败了。

Promise中reject和catch的区别

Promise的参数的函数中有reject来处理失败情况,catch方法也可以处理失败情况,那么两种方式有什么区别呢?

reject

  • 是Promise的静态方法

  • 对应then中第二个参数,如果then中没有写第二个回调,则进入catch

  • 只能捕获到Promise对象中函数的错误

  • 可以将promise 的状态改为 rejected

catch

  • 是Promise实例的方法, 对错误信息统一管理

  • 可以捕获到调用链路上的所有异常

  • 断网情况进入catch

  • 可以通过 reject 和 throw new error 来触发,但只有通过 reject 来触发,才能把promise状态改为rejected

new Promise()调用了Promise的构造函数,那么new Promise()的参数函数里的代码是同步执行还是异步执行呢?then方法是同步还是异步呢?

 new Promise(resolve=>{
      console.log(1);
      resolve(3);
  }).then(num=>{
      console.log(num);
  });
  console.log(2);
  //依次为 123
  //promise构造函数是同步执行的,then方法是异步执行的

Generator

Generators 是可以用来控制迭代器的函数。它们可以暂停,然后在任何时候恢复。

function* generatorForLoop() {
    for (let i = 0; i < 5; i += 1) {
        yield console.log(i)
    }
}
​
const genForLoop = generatorForLoop()
​
console.log(genForLoop.next()) // first console.log - 0
console.log(genForLoop.next()) // 1
console.log(genForLoop.next()) // 2
console.log(genForLoop.next()) // 3
console.log(genForLoop.next()) // 4

对比下代码,常规的循环只能一次遍历完所有值,Generator 可以通过调用 next 方法拿到依次遍历的值,让遍历的执行变得“可控”。

基本语法

定义

function* gen() {
    yield 1
    yield 2
    yield 3
}
​
let g = gen()

这个是 Generator 的定义方法,有几个点值得注意:

  1. 比普通函数多一个 *

  2. 函数内部用 yield 来控制程序的执行的“暂停”

  3. 函数的返回值通过调用 next 来“恢复”程序执行

注意:Generator 函数的定义不能使用箭头函数,否则会触发 SyntaxError 错误

yield 表达式

yield 关键字用来暂停和恢复一个生成器函数

关于 yield 表达式,要熟记几个知识点:

  1. yield 表达式的返回值是 undefined,但是遍历器对象的 next 方法可以修改这个默认值。

  2. yeild * 是委托给另一个遍历器对象或者可遍历对象

    function* gen() {
          let val
          val = yield 1
          console.log( `1:${val}` ) // 1:undefined
          val = yield 2
          console.log( `2:${val}` ) // 2:undefined
          val = yield [3, 4, 5]
          console.log( `3:${val}` ) // 3:undefined
      }

    Generator 对象的 next 方法,遇到 yield 就暂停,并返回一个对象,这个对象包括两个属性:value 和 done。``

应用场景

还是前面的异步操作,按顺序读取a.json、b.json、c.json,如果使用Generator该如何实现呢?

场景1

function request(url) {
    ajax(url, res => {
        getData.next(res)
    })
}
​
function* gen() {
    let res1 = yield request('static/a.json')
    console.log(res1)
    let res2 = yield request('static/b.json')
    console.log(res2)
    let res3 = yield request('static/c.json')
    console.log(res3)
}
let getData = gen()
getData.next()

异步编程解决方案

为什么可以使用:

因为Generator中yield关键字可以让代码暂停,也可以使用.next()让代码继续执行,根据这一特性,就可以让异步任务顺序执行。 

// 将发送ajax请求封装成一个方法
    let ajax = (url, callback) => {
      var xmlhttp = new XMLHttpRequest()
      xmlhttp.open("GET", url, true)
      xmlhttp.send()
      xmlhttp.onreadystatechange = () => {
        if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
          var res = JSON.parse(xmlhttp.responseText)
          callback(res)
        }
      }
    }
    // 定义一个require函数用于发送ajax请求
    let require = (url) => {
      ajax(url, res => {
        getData.next(res)
      })
    }
    // 使用Generator来解决异步编程
    function* gen() {
      let res1 = yield require('a.json')
      console.log(res1)
      let res2 = yield require('b.json')
      console.log(res2)
      let res3 = yield require('c.json')
      console.log(res3)
    }
    let getData = gen()
    getData.next()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值