来源:极链科技
作者:周哲

所谓“异步” ,简单说就是一个任务分成两段,先执行第一段,然后转而执行其他任务,等做好了准备,再回过头执行第二段。比如,有一个任务是读取文件进行处理,异步的执行过程就是下面这样。
常见的浏览器无响应(假死),往往就是因为某一段 Javascript 代码长时间运行(比如死循环),导致整个页面卡在这个地方,其他任务无法执行。
为了解决这个问题,Javascript 语言将任务的执行模式分成两种:同步( Synchronous )和异步( Asynchronous )。

异步编程原理
JavaScript 引擎负责解析,执行 JavaScript 代码,但它并不能单独运行,通常都得有一个宿主环境,一般如浏览器或 Node 服务器,前文说到的单线程是指在这些宿主环境创建单一线程,提供一种机制,调用 JavaScript 引擎完成多个 JavaScript 代码块的调度,这种机制就称为事件循环( Event Loop )。关于事件循环流程分解如下:

  1. 宿主环境为JavaScript 创建线程时,会创建堆 (heap) 和栈 (stack) ,堆内存储 JavaScript 对象,栈内存储执行上下文;
  2. 栈内执行上下文的同步任务按序执行,执行完即退栈,而当异步任务执行时,该异步任务进入等待状态(不入栈),同时通知线程:当触发该事件时(或该异步操作响应返回时),需向消息队列插入一个事件消息;
  3. 当事件触发或响应返回时,线程向消息队列插入该事件消息(包含事件及回调);
  4. 当栈内同步任务执行完毕后,线程从消息队列取出一个事件消息,其对应异步任务(函数)入栈,执行回调函数,如果未绑定回调,这个消息会被丢弃,执行完任务后退栈;
  5. 当线程空闲(即执行栈清空)时继续拉取消息队列下一轮消息(next tick ,事件循环流转一次称为一次 tick )。

很多的队列先后按顺序执行任务就形成了 Event异步编程实现1 :回调函数
优点:简单、容易理解和部署。
缺点:不利于代码的阅读和维护,各个部分之间高度耦合( Coupling ),流程会很混乱。2 : Promise 对象
一个 promise 可能有三种状态:等待( pending )、已完成( fulfilled )、已拒绝( rejected ) ;

resolve ,接受一个成功值,传递给绑定的 fulfilled 回调函数中。主要工作是将当前状态变为 fulfilled 状态,同时调用绑定的 fulfilled 回调函数。reject ,接受一个失败信息,传递给绑定的 rejected 回调函数中。主要工作是将当前状态变为 rejected 状态,同时调用绑定的 rejected 回调函数。then 方法返回一个 Promise 。它有两个参数,分别为 Promise 在成功和失败情况下的回调函数。
语法:

概括来说 promise 是对异步的执行结果的描述对象。3 : Generator
Generator 函数是 ES6 提供的一种异步编程解决方案 ,允许函数的暂停和恢复。
异步任务的封装:

整个过程类似于,浏览器遇到标识符 * 之后,就明白这个函数是生成器函数,一旦遇到 yield 标识符,就会将以后的函数放入此异步函数之内,待异步返回结果后再进行执行。更深一步,从内存上来讲:
普通函数在被调用时,JS 引擎会创建一个栈帧,在里面准备好局部变量、函数参数、临时值、代码执行的位置(也就是说这个函数的第一行对应到代码区里的第几行机器码),在当前栈帧里设置好返回位置,然后将新帧压入栈顶。待函数执行结束后,这个栈帧将被弹出栈然后销毁,返回值会被传给上一个栈帧。
当执行到 yield 语句时, Generator 的栈帧同样会被弹出栈外,但 Generator 在这里耍了个花招 —— 它在堆里保存了栈帧的引用(或拷贝)!这样当 it.next 方法被调用时, JS 引擎便不会重新创建一个栈帧,而是把堆里的栈帧直接入栈。因为栈帧里保存了函数执行所需的全部上下文以及当前执行的位置,所以当这一切都被恢复如初之时,就好像程序从原本暂停的地方继续向前执行了。
而因为每次 yield 和 it.next 都对应一次出栈和入栈,所以可以直接利用已有的栈机制,实现值的传出和传入。

javascript等待异步线程完成_JavaScript 中的异步原理相关推荐

  1. node.js 异步_Node.js v14中的异步本地存储是什么?

    node.js 异步 Node.js 14 is out now, and with that release, it brings in Async Local Storage support. N ...

  2. spring mvc 异步_DeferredResult – Spring MVC中的异步处理

    spring mvc 异步 DeferredResult是一个可能尚未完成的计算的容器,它将在将来提供. Spring MVC使用它来表示异步计算,并利用Servlet 3.0 AsyncContex ...

  3. PHP guzzle异步请求数据,Guzzle中的异步请求

    Guzzle中的异步请求 使用Guzzle发起异步请求 Guzzle是一个PHP的HTTP客户端,它在发起http请求时不仅可以同步发起,还可以异步发起. $client = new Client() ...

  4. java for循环 等待_在forEach循环中使用异步/等待

    在forEach循环中使用async / await是否有任何问题? 我正在尝试遍历文件数组并await每个文件的内容. import fs from 'fs-promise' async funct ...

  5. python 主程序等待 子线程_Python多线程中主线程等待所有子线程结束的方法

    Python多线程中主线程等待所有子线程结束的方法 发布时间:2020-07-30 14:39:04 来源:亿速云 阅读:77 作者:小猪 这篇文章主要讲解了Python多线程中主线程等待所有子线程结 ...

  6. 高并发 python socket send 异步_在Python中使用异步Socket编程性能测试

    ok,首先写一个python socket的server段,对开放三个端口:10000,10001,10002.krondo的例子中是每个server绑定一个端口,测试的时候需要分别开3个shell, ...

  7. 线程池异步线程中再次获取线程池资源的问题

    问题描述 在线上发生的一次问题, 在场景中有这样一个业务, 需要异步执行一个主任务, 主任务中又包含着N个子任务, 为了整个主任务能够快速处理, 又将子任务按照数量获取线程资源异步处理, 即异步线程A ...

  8. (Erlang语言)运行时中的无锁队列及其在异步线程中的应用

    本文首先介绍 Erlang 运行时中需要使用无锁队列的场合,然后介绍无锁队列的基本原理及会遇到的问题,接下来介绍 Erlang 运行时中如何通过"线程进度"机制解决无锁队列的问题, ...

  9. Erlang运行时中的无锁队列及其在异步线程中的应用

    本文首先介绍 Erlang 运行时中需要使用无锁队列的场合,然后介绍无锁队列的基本原理及会遇到的问题,接下来介绍 Erlang 运行时中如何通过"线程进度"机制解决无锁队列的问题, ...

最新文章

  1. xpath定位元素方法_测试数十次,总结了APP元素定位的万能方法
  2. cookie 和 session 机制
  3. 怎么把文件放在python目录下-python – 如何将文件下载到特定目录?
  4. CentOS 卸载OpenJdk和Tomcat开机启动
  5. PHP随笔---简述var_dump()、print_r()、echo()
  6. ccd后视摄像头_20192020年车载摄像头产业报告
  7. 泛微E-Office v9任意文件上传(CNVD-2021-49104)复现
  8. 学习笔记13--基于蜂窝移动通信的车联网技术
  9. linux离线安装postgresql,离线安装PostgreSQL
  10. 文件被别的程序打开无法删除怎么办?
  11. 深度学习day05-利用TensorFlow搭建图像分类感知机模型,并使用模型进行图片分类
  12. java.time.DateTimeException: Unable to extract ZoneId from temporal
  13. sheet_name
  14. 如何快速搭建手游平台?
  15. 读此一席话,胜读十年书:最牛情场职场语录大全
  16. Bootstrap 超大屏幕(Jumbotron)
  17. Android 设置按钮在 下滑页面按钮隐藏,上滑页面按钮显示
  18. Linux文件系统挂载的概念
  19. 几点项目里的经验教训
  20. 上海计算机5年制大专学校,上海五年制大专学校排名

热门文章

  1. win服务器系统程序原因分析
  2. springBoot+maven的打包和部署在Tomcat
  3. 批量删除文件名中的相同文字
  4. 关于vue,angularjs1,react之间的对比
  5. 关于ark取得进程的镜像文件路径
  6. 计算机毕业生求职之路
  7. 洛谷2766:[网络流24题]最长不下降子序列问题——题解
  8. windows系统命令行下常用命令收集
  9. C语言在VS2017环境下写俄罗斯方块的感悟
  10. CentOs 7.2下ELK日志分析系统搭建