JS梳理之es6异步async await 协程 迭代器

es6异步 promise 链式调用 是对回调炼狱的一种优化
这次梳理一下async await

async function fetchData() {
    const response = await fetch('https://api.example.com/data');
    const data = await response.json();
    return data;
}

// async 声明这是一个异步函数
// await 会暂停函数的执行
// 等待promise执行完成后 恢复函数的执行

最开始 分析一下yield 写一个yield 函数 分析一下 他和async await 之间的关联 相通处 怎么使用

function* generatorFunction() {
    console.log("开始");
    yield "第一个值"; // 暂停执行并返回 "第一个值"
    console.log("继续");
    yield "第二个值"; // 暂停执行并返回 "第二个值"
    console.log("结束");
}

// 创建生成器
const gen = generatorFunction();  // 类似于声明一个async 函数

// 第一次调用 next(),开始执行
console.log(gen.next()); // 输出: { value: '第一个值', done: false } 

// 第二次调用 next(),恢复执行
console.log(gen.next()); // 输出: "继续" 以及 { value: '第二个值', done: false }

// 第三次调用 next(),继续执行到结束
console.log(gen.next()); // 输出: "结束" 以及 { value: undefined, done: true }


// gen.next()   明确告诉生成器 可以进行下一步了
// 这个过程很像 拿到数据后的回调操作


这类我尝试了很久 我发现写不出来的原因就是 next可以传参 去改变yiled值 这个特性太强大 没这一步 async 写不出来

所以先写一个简化版的async函数


async function fetchData() {
    const response = await fetch('https://api.example.com/data');
    return response;
}

function* generatorFunction() {
  const p = fetch('https://api.example.com/data')
  const data = yield p
  return data
}
const gen = generatorFunction()
gen.next().value.then(res=>{
  gen.next(res)
})

再写一个复杂版本的async函数

function fn(val) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(val * 2)
        }, 1000)
    })

}
async function test(){
    const response1 = await fn(1)
    const response2 = await fn(response1)
    const response3 = await fn(response2)
    return response3
}
test()

function* generatorFunction() {
    const response1 = yield fn(1)
    const response2 = yield fn(response1)
    const response3 = yield fn(response2)
    return response3
}
const gen = generatorFunction()
gen.next().value.then(res1 => {
    console.log(res1)
    gen.next(res1).value.then(res2 => {
        console.log(res2)
        gen.next(res2).value.then(res3 => {
            console.log(gen.next(res3))
        })
    })
})

// 在之前的基础上 解决执行问题
function* generatorFunction() {
    const response1 = yield fn(1)
    const response2 = yield fn(response1)
    const response3 = yield fn(response2)
    return response3
}
const gen = generatorFunction()
function rec (paramGen ,paramRes) {
  const temp = paramGen.next()
  if(temp.done){return temp.value}
  temp.value.then(res=>{
    rec(paramGen,res)
  })
}
rec(gen)


// 上面仅仅是执行流程复刻了 进一步封装成promise

function run(gen) {
  //把返回值包装成promise
  return new Promise((resolve, reject) => {
    var g = gen()

    function _next(val) {
      let res = g.next(val)
      if(res.done) {
        return resolve(res.value);
      }
      res.value.then(val=>_next(val))
      // 这个地方是同步递归调用函数  
      // 立即执行 构建生成器
      // 立即执行 调用.next()生成器启动 
      //          执行到yield暂停执行 返回promise1 向promise1的.then方法中添加回调函数 等待2秒后 执行回调
      //          以此类推
    }
    _next();
  });
}
posted @ 2025-03-29 01:22  张正1998  阅读(42)  评论(0)    收藏  举报