JavaScript中的Promise、Generate 函数、Async 函数 说明及使用示例

本文深入探讨了JavaScript中异步编程的发展,从回调函数的“地狱”到Promise、Generator和Async函数的优雅解决方案。通过实例对比,展示了这些技术如何简化复杂的异步流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

本人之前一直做Android开发,无奈Android现在尴尬的市场环境加上公司Android项目很少,只得转而学习Web前端。过程中发现要学的东西真的太多,只靠记忆实在效果有限,只得借助博客记录其中的一些关键知识,以便自己以后能快速回顾及帮助同样有疑惑的小伙伴。

本文主要讨论JavaScript中的Promise、Generate 函数、Async 函数,对他们有个大概说明及实际场景中的一些使用方式。网上对于他们的说明文章真的很多,百度一搜一大把,读完之后让我云里雾里,感觉懂了又感觉没懂,前前后后读了几十篇文章才懵懵懂懂,实在惭愧。

Promise、Generate 函数、Async 函数之前的异步编程

废话不多说了,首先说说,在这三个函数出来之前js中的异步编程—回调,让我用代码说话

const fun1 = (value,logValue) => {

    setTimeout(()=>{

      value(logValue);

    },1000)

  }



  const fun2 = (value,logValue) => {

    setTimeout(()=>{

      value(logValue);

    },1000)

  }



  const fun3 = (value,logValue) => {

    setTimeout(()=>{

      value(logValue);

    },1000)

  }



  fun1((f1) => {

    console.log(f1);

    fun2((f2) => {

      console.log(f2);

      fun3((f3)=>{

        console.log(f3);

      },'fun3')

    },'fun2')

  },'fun1')

fun1、fun2、fun3分别模拟延时操作。实际的业务场景是,我要fun1 执行完成后,再去执行fun2,fun2执行完成后再去执行fun3,他们都是延时操作,可以看到具体实现方式,使用嵌套的方式,在fun1调用传入回调函数,在回调函数中调用fun2,又在调用fun2的同时传入回调,在回调函数中调用fun3,这种方式让代码嵌套层数过多,代码不够优雅,用网上的话说,这是“回调地狱”。(我本人倒是觉得还好,最多代码楼层太多,看起来不优雅而已。实际情况中我好像也没用碰到太多层的情况)

 

Promise的说明及实现方式

我们先看下Promise的创建方式

new Promise(function(resolve, reject){

    if(true){

      resolve('sucess')

    }else{

      reject('fail')

    }

  })

看起来这还是回调,成功的时候回调 resole,失败的时候调用reject。其实Promise本身只是解决“回调地狱”而出现的另一种“实现方式”(换了一种写法)。那Promise的具体写法是怎样的呢?我还是用上面的案例,这一次我们换成Promised 的写法。 

 const fun1 = () => {

    return new Promise((resolve, reject)=>{

      setTimeout(()=>{

        resolve('fun1');

      },1000)

    })

  }



  const fun2 = (val) => {

    return new Promise((resolve, reject)=>{

      setTimeout(()=>{

        resolve(val);

      },1000)

    })

  }



  const fun3 = (val) => {

    return new Promise((resolve, reject)=>{

      setTimeout(()=>{

        resolve(val);

      },1000)

    })

  }



  fun1().then((v1)=>{

    console.log(v1)

    return fun2('fun2')

  }).then((v2)=>{

    console.log(v2)

    return fun3('fun3')

  }).then((v3)=>{

    console.log(v3)

  })

我们稍微改造了下fun1、fun2、fun3.让他们都返回的了Promise对象,之后调用then方法,并传入回调,then中的回调方法,就是resolve。Promise让所有的回调全部用了then进行传入,这种链式写法,看上去会清晰些。(网上说的,我看来看去还是觉得回调式更舒服,我仿佛是个智障)

 

Generate 函数的说明及实现

Generate 函数的基本语法

function * fun(x){

  const a = yield x+1;

  yield a;

}

相比普通函数,多了一个“*” 已经函数体中多了 一个 yield的关键词。Generate 函数相比普通函数,最大的调用区别是,如果把普通函数比喻成马车,这货就是一个耕田的牛,不打他不走。普通的函数调用,就一溜到底,这货执行的时候。首先给返回一个迭代器。你每次调用 next()方法。他往下走一下,直到遇到yield或者return ;

还是用我们开始的案例来换个写法说明吧。

let f;

 const fun1 = (value) => {

    setTimeout(()=>{

      value('fun1');

    },1000)

  }



  const fun2 = (value) => {

    setTimeout(()=>{

      value('fun2');

    },1000)

  }



  const fun3 = (value) => {

    setTimeout(()=>{

      value('fun3');

    },1000)

  }



  const callback = (t)=>{

      console.log(t)

      f.next() //在这个回调函数一致调用next,以便让他自动走下去

    }



 

  function * runAll(){

    yield fun1(callback)

    yield fun2(callback)

    yield fun3(callback)

  }



  f = runAll()  //给了你一个迭代器,等于啥也没干。

  f.next(); //启动一下

我之前有个很大的误区,认为yield是等执行完成才会走next。所以我连续调用了三次。f.next()结果三个方法的打印同时出现,显然是不对的。

 

Async函数的说明及用法

网上对Async的一致说明是,这就是Generate函数的升级版,既然是升级那更好用啦。先看看他的语法

async function fun (x){

    const a = await x + 1;

    await a;

  }

相当于Generate 把“*“变成了async 把 yield变成了 await,就这样?然后不是,搞这么大动静,只是换个写法,不是闲的蛋疼么。Async函数可以像普通函数一样,一溜到底,而且不是每次都要next()。另外 await后返回的是Promise对象。

const fun1 = () => {

    return new Promise((resolve, reject)=>{

      setTimeout(()=>{

        resolve('fun1');

        console.log('fun1');

       

      },1000)

    })

  }



  const fun2 = () => {

    return new Promise((resolve, reject)=>{

      setTimeout(()=>{

        resolve('fun2');

        console.log('fun2');

      },1000)

    })

  }



  const fun3 = () => {

    return new Promise((resolve, reject)=>{

      setTimeout(()=>{

        resolve('fun3');

        console.log('fun3');

      },1000)

    })

  }



  async function runAll (){

    await fun1();

    await fun2();

    await fun3();

  }



  runAll();

async之所以能一溜到底的走下去,是三个函数中都要调用resolve方法,各位可以拿掉resolve看看效果。我贴上代码,给位可以直接放在浏览器允许看看允许执行结果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值