生成器和promise推导async和await

x33g5p2x  于2022-03-11 转载在 其他  
字(2.5k)|赞(0)|评价(0)|浏览(392)

一、写在前面
Promise异步处理,我们通常使用awaitasync来进行处理。下面我们将深入探究一下awaitasync的原理。我们使用一个例子进行说明。
二、例子
我们现在模拟一个场景,当我们先请求完一个请求之后,拿到返回值,再加上-----去继续发起请求。然后再次拿到返回值之后,再加上+++++去发起请求。
一、最基本的写法

function RequestData(url) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(url)
    }, 2000)
  })
}

RequestData("hello").then(res => {
  RequestData(res + '-----').then(res => {
    RequestData(res + "+++++").then(res => {
      console.log(res)
    })
  })
})

//hello-----+++++

上面是最基本的写法,就是使用then嵌套,拿到上一个结果的值,然后再进行拼接参数,再次发起请求。
二、稍微优化一波

function RequestData(url) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(url)
    }, 2000)
  })
}

RequestData("hello")
  .then(res => res + '-----')
  .then(res => res + '+++++')
  .then(res => console.log(res))

  //hello-----+++++

如上述代码所示,就要比第一个简单一些,使用的是then()return之后的值,会被包裹一层Promsie
三、进一步优化

function RequestData(url) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(url)
    }, 2000)
  })
}

function* generator(url) {
  const res1 = yield RequestData(url)
  const res2 = yield RequestData(res1)
  const res3 = yield RequestData(res2)
}

let gener = generator("hello")
gener.next().value.then(res => {
  gener.next(res + '-----').value.then(res => {
    gener.next(res + '+++++').value.then(res => {
      console.log(res)
    })
  })
})

//hello-----+++++

上面代码我们使用迭代器,当上一个执行出现结果是,然后我们将其作为参数传入下一个操作中。
四、再进一步优化,使用递归来代替上述代码

function RequestData(url) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(url)
    }, 2000)
  })
}

function* generator(url) {
  const res1 = yield RequestData(url)
  const res2 = yield RequestData(res1 + '-----')
  const res3 = yield RequestData(res2 + '+++++')
  console.log(res3)
}

function createGen(generator) {
  let gener = generator('hello')
  function exact(res) {
    let result = gener.next(res)
    if(result.done) {
      return result.value
    }
    result.value.then(res => {
      exact(res)
    })
  }
  exact()
}

createGen(generator)
//hello-----+++++

5、也可以使用co这个库来解决

const { co } = require("co")

function RequestData(url) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(url)
    }, 2000)
  })
}

function* generator(url) {
  const res1 = yield RequestData(url)
  const res2 = yield RequestData(res1 + '-----')
  const res3 = yield RequestData(res2 + '+++++')
  console.log(res3)
}

co(generator('hello'))

6、第五个比较像await/async了

const { co } = require("co")

function RequestData(url) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(url)
    }, 2000)
  })
}

async function generator(url) {
  const res1 = await RequestData(url)
  const res2 = await RequestData(res1 + '------')
  const res3 = await RequestData(res2 + "+++++++")
  console.log(res3)
}

generator("hello")
//hello----+++++

此时是不是对await和async有了更深刻的认识了。

相关文章