资讯专栏INFORMATION COLUMN

JS—异步、回调、高阶函数

Dean / 2786人阅读

摘要:而是在调用发出后,被调用者通过状态通知来通知调用者,或通过回调函数处理这个调用。请求程序发出请求,从服务器端获取数据,并设置了回调函数。然后,浏览器会设置侦听来自网络的响应,拿到数据后,将该回调函数插入到事件循环。

并发与并行

并发是指两个或多个事件链随时间发展交替执行,以至于从更高的层次来看,就像是同时运行(但在任意时刻只处理一个事件)

并发的关键是你有处理多个任务的能力,不一定同时。

并行的关键是你有同时处理多个任务的能力。

并发和并行都可以是很多个线程,就看这些线程能不能同时被(多个)cpu执行,如果可以就说明是并行,而并发是多个线程被(一个)cpu 轮流切换着执行。

区别:是否【同时】

单线程事件循环是并发的一种形式

并发的实现方式:多进程,多线程,事件循环

我的理解是:并发是多个逻辑流交替执行,看起来像是同时运行,其实任意时刻只能处理一个;而并行是真正的同时执行。

同步与异步

同步和异步关注的是消息通信机制 (synchronous communication/ asynchronous communication)

同步,就是在发出一个调用时,在没有得到结果之前,该调用就不返回。但是一旦调用返回,就得到返回值了。

异步则是相反,调用在发出之后,这个调用就直接返回了,所以没有返回结果。换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果。而是在调用发出后,被调用者通过状态、通知来通知调用者,或通过回调函数处理这个调用。

阻塞与非阻塞

阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态

阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。

非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。

我的理解:异步阻塞是没有必要的;ajax请求最好不要设置为同步,chrome浏览器会警告

阻塞与非阻塞,同步与异步知乎链接
阻塞与非阻塞与是否同步异步无关

事件循环

机制:while(true)每轮循环取出事件队列中的队头事件执行,事件队列(先进先出)。

setTimeout()是设定一个定时器,当定时器到时后,环境会把回调函数放到事件循环中。如果此时事件队列中有多个事件,那么该回调就会等待,所以setTimeout定时器的精度可能不高,只能确保回调函数不会在指定的时间间隔之前运行。

AJAX请求:JS程序发出ajax请求,从服务器端获取数据,并设置了回调函数。发出请求的时候,JS引擎会通知宿主环境,让其完成了网络请求,拿到数据后执行该回调函数。然后,浏览器会设置侦听来自网络的响应,拿到数据后,将该回调函数插入到事件循环。

竞态条件:函数执行顺序的不确定性(来自于插入事件队列顺序的不确定性)

竞态条件可能会导致结果的不确定性,所以需要通过协调交互顺序来解决这种情况。

并发协作:JS中我的理解是:将大任务分解为多个小任务,分别利用异步机制插入到事件队列中,例如可利用setTimeout(f,0)将小任务插入到事件队列中,如果事件队列目前有待执行的事件就可以先执行,以此来避免大任务阻塞事件队列中其他任务的执行。

JavaScript单线程与异步

why单线程:作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的问题。

why异步:我的理解:浏览器应用决定了会有很多网络请求,会有很多不可控的速度因素,浏览器是直接和用户交互,用户交互体验很重要,所以不能阻塞,但同步非阻塞处理起来会很麻烦,因为同步需要编写代码去检测任务是否执行成功。所以就用异步,异步是通信机制决定了调用在发出之后就可以直接返回。

所有同步任务执行完毕,系统就会循环读取事件队列。

阮一峰的链接:http://www.ruanyifeng.com/blo...

深入理解事件循环

深入事件循环

回调

回调是JS中最基础的异步模式

回调地狱:1)难以编写,大脑的思维方式不适应面向回调的异步代码。2)为了处理可能出现的各种情况,只能在回调的每个步骤中硬编码,造成代码的复杂与重复,难以重用和维护。

信任问题:控制反转,即把自己程序的一部分执行控制交给了某个第三方。

高阶函数

JS作为一门完整的面向对象的编程语言,借鉴了函数式语言的特性,比如闭包、高阶函数等。

高阶函数: 函数可作为参数被传递,函数可作为返回值输出。

函数作为参数被传递:

1)回调函数,即将变化部分的代码封装为函数,将函数作为参数传递。本来可以将变化的部分抽离出来,形成两个函数,但实际上这两个函数有依赖关系,所以只能参数调用,放到同一个函数中执行。
2)Array.prototype.sort 可以传入函数作为排序规则。

异步控制台

JS调试最好使用断点,因为console.log()是由宿主环境添加到JS中,控制台I/O处理可能会有延时。

《你不知道的javascript中卷》第二部分异步和性能 1.1 异步控制台部分:

并没有什么规范或一组需求指定console.* 方法族如何工作——它们并不是JavaScript 正式
的一部分,而是由宿主环境(请参考本书的“类型和语法”部分)添加到JavaScript 中的。因此,不同的浏览器和JavaScript 环境可以按照自己的意愿来实现,有时候这会引起混淆。

尤其要提出的是,在某些条件下,某些浏览器的console.log(..) 并不会把传入的内容立即输出。出现这种情况的主要原因是,在许多程序(不只是JavaScript)中,I/O 是非常低速的阻塞部分。所以,(从页面/UI 的角度来说)浏览器在后台异步处理控制台I/O 能够提高性能,这时用户甚至可能根本意识不到其发生。

例如在mousemove监听函数中console.log,是不会打印出内容的(mousemove触发太频繁,而console.log属于I/O操作,浏览器为了性能考虑,会将这种频繁I/O放到后台运行)。

解决方案: 如果断点调试不方便的话,可以将需要打印的内容,挂载到window对象,mousemove完成后再打印出来看。

更多博客: https://github.com/Lmagic16/blog

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/98363.html

相关文章

  • 尚学堂 react -后台管理系统开发流程

    摘要:项目开发准备描述项目技术选型接口接口文档测试接口启动项目开发使用脚手架创建项目开发环境运行生产环境打包运行管理项目创建远程仓库创建本地仓库配置将本地仓库推送到远程仓库在本地创建分支并推送到远程如果本地有修改新的同事克隆仓库如果远程修 day01 1. 项目开发准备 1). 描述项目 2). 技术选型 3). API接口/接口文档/测试接口 2. 启动项目开发 1). 使用react...

    lemon 评论0 收藏0
  • js处理异步函数:从callback到promise

    摘要:在处理异步回调函数的情况有着越来越值得推崇的方法及类库,下面会依次介绍处理异步函数的发展史,及源码解读。而对象的状态,是由第一个的参数成功回调函数或失败回调函数的返回值决定的。 函数的执行分为同步和异步两种。同步即为 同步连续执行,通俗点讲就是做完一件事,再去做另一件事。异步即为 先做一件事,中间可以去做其他事情,稍后再回来做第一件事情。同时还要记住两个特性:1.异步函数是没有返回值的...

    dance 评论0 收藏0
  • PHP下的异步尝试三:协程的PHP版thunkify自动执行器

    摘要:函数并不是生成器协程函数自动执行的唯一方案。因为自动执行的关键是,必须有一种机制,自动控制生成器协程函数的流程,接收和交还程序的执行权。回调函数可以做到这一点,对象也可以做到这一点。本系列的下一篇,将介绍基于的实现的自动执行器。 PHP下的异步尝试系列 如果你还不太了解PHP下的生成器和协程,你可以根据下面目录翻阅 PHP下的异步尝试一:初识生成器 PHP下的异步尝试二:初识协程 P...

    wudengzan 评论0 收藏0
  • JS 异步错误捕获二三事

    摘要:以及异步代码在中是特别常见的,我们该怎么做才比较无法捕获的情况这段代码中,的回调函数抛出一个错误,并不会在中捕获,会导致程序直接报错崩掉。用捕获异步错误把异步操作用包装,通过内部判断,把错误,在外面通过捕获。 引入 我们都知道 try catch 无法捕获 setTimeout 异步任务中的错误,那其中的原因是什么。以及异步代码在 js 中是特别常见的,我们该怎么做才比较? 无法捕获的...

    Java_oldboy 评论0 收藏0
  • 【Node Hero】3. 理解异步编程

    摘要:异步编程在传统编程实践中,大多数操作都是同步发生的。中的异步编程异步是一种输入输出处理的形式,它允许在传输完成之前,其它处理能继续进行。 本文转载自:众成翻译译者:网络埋伏纪事链接:http://www.zcfy.cc/article/1759原文:https://blog.risingstack.com/node-hero-async-programming-in-node-js/ ...

    kevin 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<