Promise_async/await_generator使用

52 阅读2分钟

创建Promise

异步执行,先请求完接口1,再拿接口1返回的数据,去当做接口2的请求参数

  const promise = (num) => {
    return new Promise(function (resolve, reject) {
      console.log(6)
      resolve(num * 2);
    });
  };
  
  const handleClick = () => {
    console.log(1);
    setTimeout(() => {
      console.log(2);
    });
    promise(3)
      .then((arg) => {
        console.log(arg)
        promise(arg).then((arg) => console.log(arg));
      })
    console.log(5);
  };

执行顺序 1 6 5 6 6 12 2

使用async/await

await后面接Promise

  const handleClick = (() => {
    function request(num) {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve(num * 2)
        }, 2000)
      })
    }
    
    async function fn() {
      let aaa = await request(1)
      // 等待2秒
      console.log(aaa)
      let bbb = await request(aaa)
      // 再等待2秒
      console.log(bbb)
    }
    fn()
  })

await后面不接Promise

  const handleClick = (() => {
    function request(num) {
      return num * 2
    }
    
    async function fn() {
      // 几乎同时打印,但能拿到aaa的结果作为参数
      let aaa = await request(1)
      console.log(aaa)
      let bbb = await request(aaa)
      console.log(bbb)
    }
    fn()
  })   

如果await后面接的不是Promise的话,有可能其实是达不到排队的效果的

async是一个位于function之前的前缀,只有async函数中,才能使用await

async函数执行完会自动返回一个状态为fulfilled的Promise,也就是成功状态,但是值却是undefined,那要怎么才能使值不是undefined呢?很简单,函数有return返回值就行了

    async function fn (num) {
      return num
    }
    console.log(fn) // [AsyncFunction: fn]
    console.log(fn(10)) // Promise {<fulfilled>: 10}
    fn(10).then(res => console.log(res)) // 10

generator函数拓展

基本用法

generator函数跟普通函数在写法上的区别就是,多了一个星号*,并且只有在generator函数中才能使用yield,什么是yield呢,他相当于generator函数执行的中途暂停点,比如下方有3个暂停点。而怎么才能暂停后继续走呢?那就得使用到next方法next方法执行后会返回一个对象,对象中有value 和 done两个属性

  • value:暂停点后面接的值,也就是yield后面接的值
  • done:是否generator函数已走完,没走完为false,走完为true
    function* gen() {
      yield 1
      yield 2
      yield 3
      return 4
    }
    const g = gen()
    console.log(g.next()) // { value: 1, done: false }
    console.log(g.next()) // { value: 2, done: false }
    console.log(g.next()) // { value: 3, done: false }
    console.log(g.next()) // { value: 4, done: true }

实现具有async功能的函数

    function foo(num) {
      return new Promise((resolve) => {
        setTimeout(() => {
          resolve(num * 2);
        }, 1000);
      });
    }
    
    function generatorToAsync(generatorFn) {
      return function() {
        const gen = generatorFn.apply(this, arguments) // gen有可能传参

        // 返回一个Promise
        return new Promise((resolve, reject) => {

          function go(key, arg) {
            let res
            try {
              res = gen[key](arg) // 这里有可能会执行返回reject状态的Promise
            } catch (error) {
              return reject(error) // 报错的话会走catch,直接reject
            }

            // 解构获得value和done
            const { value, done } = res
            if (done) {
              // 如果done为true,说明走完了,进行resolve(value)
              return resolve(value)
            } else {
              // 如果done为false,说明没走完,还得继续走

              // value有可能是:常量,Promise,Promise有可能是成功或者失败
              return Promise.resolve(value).then(val => go('next', val), err => go('throw', err))
            }
          }

          go("next") // 第一次执行
        })
      }
    }
    
  function* gen() {
    const num1 = yield foo(1);
    const num2 = yield foo(num1);
    const num3 = yield foo(num2);
    return num3;
  }
  const asyncFn = generatorToAsync(gen);
    const asyncFn = generatorToAsync(gen)

    asyncFn().then(res => console.log(res))

参考链接:juejin.cn/post/700703…