JS异步编程的解决方案_js异步解决方案-程序员宅基地

技术标签: 转载、学习  前端  typescript  javascript  

js解决异步编程有6种方案:

在这里插入图片描述
1.1 回调函数

异步编程的最基本方法,把任务的第二段单独写在一个函数里面,等到重新执行这个任务的时候,就直接调用这个函数。

  • 优点:简单、容易理解和实现。
  • 缺点:多次调用会使代码结构混乱,形成回调地狱。
function sleep(time, callback) {
    setTimeout(() => {
        // 一些逻辑代码
        callback();
    }, time);
}

1.3 发布/订阅

发布/订阅模式在观察者模式的基础上,在目标和观察者之间增加一个调度中心。订阅者(观察者)把自己想要订阅的事件注册到调度中心,当该事件触发的时候,发布者(目标)发布该事件到调度中心,由调度中心统一调度订阅者注册到调度中心的处理代码。

1.4 Promise

Promise 是异步编程的一种解决方案,也是一个构造函数,是为解决回调函数地狱这个问题而提出的,它不是新的语法功能,而是一种新的写法,允许将回调函数的嵌套改为链式调用。

  • 优点:将回调函数的嵌套改为了链式调用;使用then方法以后,异步任务的两端执行看的更加清楚。
    缺点:

这里是引用

  • Promise 的最大问题是代码冗余,原来的任务被 Promise 包装了一下,不管什么操作,一眼看去都是一堆then,原来的语义变得很不清楚。
  • 无法取消Promise,一旦新建它就会立即执行,无法中途取消。
  • 如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。
  • 当处于Pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。
// Promise 构造函数
let p=new Promise(function(resolve,reject){
  if(true){
    resolve('承诺兑现了')
  }else{
    reject('承诺没兑现')
  }
});  //p=>承诺对象
console.log(p)
 
function getRandom(){
  return new Promise(function(resolve,reject){   
    let Random=Math.random() //获取随机数 0-1
      if(Random>0.5){
        resolve('你成功了:'+Random)
      }else{
        reject('你失败了:'+Random)
      }
  })
}
let r=getRandom()//获取承诺对象
console.log(r)

1.5 Generator

Generator 函数是ES6提供的一种异步编程解决方案,语法行为与传统函数完全不同。其最大特点是可以控制函数的执行。Generator函数是将函数分步骤阻塞 ,只有主动调用next() 才能进行下一步

  • Generator 函数有多种理解角度。语法上,首先可以把它理解成,Generator 函数是一个状态机,封装了多个内部状态。 执行
  • Generator 函数会返回一个遍历器对象(迭代对象),也就是说,Generator
  • 函数除了状态机,还是一个遍历器对象生成函数。返回的遍历器对象,可以依次遍历 Generator 函数内部的每一个状态。
  • 形式上,Generator函数是一个普通函数,但是有两个特征。一是,function关键字与函数名之间有一个星号;二是,函数体内部使用yield表达式,定义不同的内部状态(yield在英语里的意思就是“产出”)。
  • 可暂停函数, yield可暂停,next方法可启动,每次返回的是yield后的表达式结果。
  • yield表达式本身没有返回值,或者说总是返回undefined。next方法可以带一个参数,该参数就会被当作上一个yield表达式的返回值。
  • 优点:异步操作表示的很简洁,此外可以控制函数的执行。
  • 缺点:流程管理不方便,不能实现自动化的流程管理。
function* genF() {
    yield 'come on!';
    yield 'Front End Engineer';
    return 'goood';
}
 
const gF = genF();
gF.next();// {value: "come on!", done: false}
gF.next();// {value: "Front End Engineer", done: false}
gF.next();// {value: "goood", done: true}
gF.next();// {value: undefined, done: true}

Generator函数的调用方法与普通函数一样,也是在函数名后面加上一对圆括号。不同的是,调用Generator函数后,该函数并不执行,返回的也不是函数运行结果,而是一个指向内部状态的指针对象(迭代器对象),我们可以通过调用 next 方法,使得指针移向下一个状态

1.6 async/await

ES2017 标准引入了async函数,使得异步操作变得更加方便。简言之,该函数就是Generator函数的语法糖。 async/await 函数的实现,就是将 Generator 函数和自动执行器,包装在一个函数里。async函数中的await接收一个Promise对象。

async 函数就是 Generator 函数的语法糖。使得异步操作变得更加⽅便。 async 函数就 是将 Generator 函数的星号( * )替换成 async ,将 yield 替换成 await ,仅此⽽已。 异步函数的运⾏结果为Promise对象,异步函数内部的返回值会作为 then⽅法回调函数的参数。(不需要使用.then方法,不需要使用回调函数)

  • 优点:内置执行器,可以自动执行;语义相比Generator更加清晰;返回值是Promise,比Generator函数的返回值是Iterator对象操作更加方便。
  • 缺点:增加学习成本。
 
    // 异步函数同步化
    async function gen(){
      let r=await axios.get(baseURL+'/index/article/pageQuery?page=1&pageSize=10');
        console.log(r);       
    }
    //await 命令后⾯是⼀个 Promise 对象,返回该对象的结果。如果不是 Promise 对象,就直接返回对应的值。
 
    gen()

async、await将异步强行转换为同步处理。
async 函数返回的是一个 Promise 对象。

wait 可以用于等待一个 async 函数的返回值——这也可以说是 await 在等 async 函数,但要清楚,它等的实际是一个返回值。注意到 await 不仅仅用于等 Promise 对象,它可以等任意表达式的结果,所以,await 后面实际是可以接普通函数调用或者直接量的。

async 会将其后的函数(函数表达式或 Lambda)的返回值封装成一个 Promise 对象,而 await 会等待这个 Promise 完成,并将其 resolve 的结果返回出来。
async/await 的优势在于处理 then 链

1、Async—声明一个异步函数(async function someName(){…})

  • 自动将常规函数转换成Promise,返回值也是一个Promise对象
  • 只有async函数内部的异步操作执行完,才会执行then方法指定的回调函数
  • 异步函数内部可以使用await

2、Await—暂停异步的功能执行(var result = await someAsyncCall()

  • 放置在Promise调用之前,await强制其他代码等待,直到Promise完成并返回结果
  • 只能与Promise一起使用,不适用与回调
  • 只能在async函数内部使用

同步方法:调用时需要等待返回结果,才可以继续往下执行业务

异步方法:调用时无须等待返回结果,可以继续往下执行业务,不会产生阻塞。

await的作用是等待异步Task完成,且不是阻塞的。产生异步函数同步化效果。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_43834567/article/details/125130224

智能推荐

oracle 12c 集群安装后的检查_12c查看crs状态-程序员宅基地

文章浏览阅读1.6k次。安装配置gi、安装数据库软件、dbca建库见下:http://blog.csdn.net/kadwf123/article/details/784299611、检查集群节点及状态:[root@rac2 ~]# olsnodes -srac1 Activerac2 Activerac3 Activerac4 Active[root@rac2 ~]_12c查看crs状态

解决jupyter notebook无法找到虚拟环境的问题_jupyter没有pytorch环境-程序员宅基地

文章浏览阅读1.3w次,点赞45次,收藏99次。我个人用的是anaconda3的一个python集成环境,自带jupyter notebook,但在我打开jupyter notebook界面后,却找不到对应的虚拟环境,原来是jupyter notebook只是通用于下载anaconda时自带的环境,其他环境要想使用必须手动下载一些库:1.首先进入到自己创建的虚拟环境(pytorch是虚拟环境的名字)activate pytorch2.在该环境下下载这个库conda install ipykernelconda install nb__jupyter没有pytorch环境

国内安装scoop的保姆教程_scoop-cn-程序员宅基地

文章浏览阅读5.2k次,点赞19次,收藏28次。选择scoop纯属意外,也是无奈,因为电脑用户被锁了管理员权限,所有exe安装程序都无法安装,只可以用绿色软件,最后被我发现scoop,省去了到处下载XXX绿色版的烦恼,当然scoop里需要管理员权限的软件也跟我无缘了(譬如everything)。推荐添加dorado这个bucket镜像,里面很多中文软件,但是部分国外的软件下载地址在github,可能无法下载。以上两个是官方bucket的国内镜像,所有软件建议优先从这里下载。上面可以看到很多bucket以及软件数。如果官网登陆不了可以试一下以下方式。_scoop-cn

Element ui colorpicker在Vue中的使用_vue el-color-picker-程序员宅基地

文章浏览阅读4.5k次,点赞2次,收藏3次。首先要有一个color-picker组件 <el-color-picker v-model="headcolor"></el-color-picker>在data里面data() { return {headcolor: ’ #278add ’ //这里可以选择一个默认的颜色} }然后在你想要改变颜色的地方用v-bind绑定就好了,例如:这里的:sty..._vue el-color-picker

迅为iTOP-4412精英版之烧写内核移植后的镜像_exynos 4412 刷机-程序员宅基地

文章浏览阅读640次。基于芯片日益增长的问题,所以内核开发者们引入了新的方法,就是在内核中只保留函数,而数据则不包含,由用户(应用程序员)自己把数据按照规定的格式编写,并放在约定的地方,为了不占用过多的内存,还要求数据以根精简的方式编写。boot启动时,传参给内核,告诉内核设备树文件和kernel的位置,内核启动时根据地址去找到设备树文件,再利用专用的编译器去反编译dtb文件,将dtb还原成数据结构,以供驱动的函数去调用。firmware是三星的一个固件的设备信息,因为找不到固件,所以内核启动不成功。_exynos 4412 刷机

Linux系统配置jdk_linux配置jdk-程序员宅基地

文章浏览阅读2w次,点赞24次,收藏42次。Linux系统配置jdkLinux学习教程,Linux入门教程(超详细)_linux配置jdk

随便推点

matlab(4):特殊符号的输入_matlab微米怎么输入-程序员宅基地

文章浏览阅读3.3k次,点赞5次,收藏19次。xlabel('\delta');ylabel('AUC');具体符号的对照表参照下图:_matlab微米怎么输入

C语言程序设计-文件(打开与关闭、顺序、二进制读写)-程序员宅基地

文章浏览阅读119次。顺序读写指的是按照文件中数据的顺序进行读取或写入。对于文本文件,可以使用fgets、fputs、fscanf、fprintf等函数进行顺序读写。在C语言中,对文件的操作通常涉及文件的打开、读写以及关闭。文件的打开使用fopen函数,而关闭则使用fclose函数。在C语言中,可以使用fread和fwrite函数进行二进制读写。‍ Biaoge 于2024-03-09 23:51发布 阅读量:7 ️文章类型:【 C语言程序设计 】在C语言中,用于打开文件的函数是____,用于关闭文件的函数是____。

Touchdesigner自学笔记之三_touchdesigner怎么让一个模型跟着鼠标移动-程序员宅基地

文章浏览阅读3.4k次,点赞2次,收藏13次。跟随鼠标移动的粒子以grid(SOP)为partical(SOP)的资源模板,调整后连接【Geo组合+point spirit(MAT)】,在连接【feedback组合】适当调整。影响粒子动态的节点【metaball(SOP)+force(SOP)】添加mouse in(CHOP)鼠标位置到metaball的坐标,实现鼠标影响。..._touchdesigner怎么让一个模型跟着鼠标移动

【附源码】基于java的校园停车场管理系统的设计与实现61m0e9计算机毕设SSM_基于java技术的停车场管理系统实现与设计-程序员宅基地

文章浏览阅读178次。项目运行环境配置:Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:Springboot + mybatis + Maven +mysql5.7或8.0+html+css+js等等组成,B/S模式 + Maven管理等等。环境需要1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。_基于java技术的停车场管理系统实现与设计

Android系统播放器MediaPlayer源码分析_android多媒体播放源码分析 时序图-程序员宅基地

文章浏览阅读3.5k次。前言对于MediaPlayer播放器的源码分析内容相对来说比较多,会从Java-&amp;amp;gt;Jni-&amp;amp;gt;C/C++慢慢分析,后面会慢慢更新。另外,博客只作为自己学习记录的一种方式,对于其他的不过多的评论。MediaPlayerDemopublic class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal..._android多媒体播放源码分析 时序图

java 数据结构与算法 ——快速排序法-程序员宅基地

文章浏览阅读2.4k次,点赞41次,收藏13次。java 数据结构与算法 ——快速排序法_快速排序法