回调函数

JavaScript并发模型和事件循环

被刻印的时光 ゝ 提交于 2019-12-29 02:40:30
  1、简介    JS有一个基于“事件循环”的并发模型。 这个模型和其他语言(如C和Java)的模型不太一样。   下图描述的是一个理论模型,现代JS引擎在此基础上实现和进行了很多优化:   2、模型详细介绍   1)相关概念   (1)栈Stack:如下例,在调用g之前,以及在g返回之后,栈都为空。 function f(b) { var a = 12; return a + b + 35; } function g(x) { var m = 4; return f(m * x); } g(21);   (2)堆:这里不介绍。   (3)队列: 待处理消息的列表,每条消息都关联一个回调函数。    JavaScript是单线程的( 多进程/多线程往往有更大的内存开销、上下文切换开销和数据竞争问题等 ),这意味着需要有一个队列保存异步执行的代码。   I、入队操作。例如,某个按钮被按下时,它的事件处理器代码被添加到队列;接收到某个Ajax响应时,回调函数的代码被添加到队列; 对于定时器,当指定时间过去后将其回调函数的代码添加到队列。   II、出队操作。 队列中没有任何代码是立刻执行的,但一旦进程空闲(此时栈为空)则尽快执行 。进程每次从队列中取出一条消息并调用其回调函数( 异步操作的结果通过回调函数获得 )。这使得栈变为非空。当栈再次变为空时,表示该消息处理完毕。   (4

JavaScript 运行机制详解:Event Loop

不想你离开。 提交于 2019-12-29 02:39:28
转自: http://www.ruanyifeng.com/blog/2014/10/event-loop.html 一、为什么JavaScript是单线程? JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。 作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准? 所以,为了避免复杂性,从一诞生,JavaScript就是单线程,这已经成了这门语言的核心特征,将来也不会改变。 为了利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,但是子线程完全受主线程控制,且不得操作DOM。所以,这个新标准并没有改变JavaScript单线程的本质。 二、任务队列 单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等着。 如果排队是因为计算量大,CPU忙不过来,倒也算了,但是很多时候CPU是闲着的,因为IO设备(输入输出设备)很慢(比如Ajax操作从网络读取数据),不得不等着结果出来,再往下执行。

单线程JavaScript

耗尽温柔 提交于 2019-12-29 02:38:42
最近在阅读《你不知道的JavaScript中卷》,当我看到第二部分介绍异步和回调函数的一些知识时,由于该书在第二部分1、2章对线程、事件循环的概念介绍的并非详细,因此引发了我的一系列思考。于是写下这篇小文章,记录自己对该知识点的学习和思考。 javascript单线程 由于JavaScript是单线程语言,因此,在一个进程上,只能运行一个线程,而不能多个线程同时运行。也就是说JavaScript不允许多个线程共享内存空间。因此,如果有多个线程想同时运行,则需采取排队的方式,即只有当前一个任务执行完毕,后一个任务才开始执行。 任务队列 在JavaScript中,所有任务可以分为两种,一种是同步任务,一种是异步任务。 同步任务 指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,后一个任务才会执行; 异步任务 指的是不进入主线程、而进入任务队列的任务,只有当主线程上的所有同步任务执行完毕之后,主线程才会读取任务队列,开始执行异步任务。 单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务不得不一直等待。那么这样的JavaScript的执行不是很慢吗?特别是对于长时间任务执行的时候,那么其他的任务就得不到执行。考虑这种原因,JS中将这些耗时的I/O等操作封装成了异步的方法,也就是通过 回调函数 的方式。等到同步任务执行完毕

javaScript异步编程

一曲冷凌霜 提交于 2019-12-29 02:38:11
一、为什么JavaScript是单线程? JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊。 JavaScript的单线程,与它的用途有关。作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准? 所以,为了避免复杂性,从一诞生,JavaScript就是单线程,这已经成了这门语言的核心特征,将来也不会改变。 为了利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,但是子线程完全受主线程控制,且不得操作DOM。所以,这个新标准并没有改变JavaScript单线程的本质。 二、任务队列 单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等着。 如果排队是因为计算量大,CPU忙不过来,倒也算了,但是很多时候CPU是闲着的,因为IO设备(输入输出设备)很慢(比如Ajax操作从网络读取数据),不得不等着结果出来,再往下执行。 JavaScript语言的设计者意识到

深入理解Javascript单线程谈Event Loop

此生再无相见时 提交于 2019-12-29 02:37:22
假如面试回答 js 的运行机制时,你可能说出这么一段话: “Javascript 的事件分同步任务和异步任务,遇到同步任务就放在执行栈中执行,而碰到异步任务就放到任务队列之中,等到执行栈执行完毕之后再去执行任务队列之中的事件。 ” 但你能说出背后的原因吗? 1. 线程与进程 进程 :是系统资源分配和调度的单元。一个运行着的程序就对应了一个进程。一个进程包括了运行中的程序和程序所使用到的内存和系统资源。 线程 :线程是进程下的执行者,一个进程至少会开启一个线程(主线程),也可以开启多个线程。 2.同步和异步 同步和异步关注的是 : 消息 ( 结果 ) 通信机制。 同步 : 发出调用 后 ,在没有得到结果前,该调用不返回。但是一旦调用返回,就得到返回值 异步 : 发出调用后,调用直接返回,没有返回结果。但结果由回调函数给出,至于什么时候给出,不知道。(这个回调函数肯定是在当前 js 执行完后才执行) 3.阻塞与非阻塞 阻塞和非阻塞关注的是 : 程序在等待调用结果时的 状态 . 阻塞调用 : 调用结果返回之前,当前线程被挂起。调用线程只有在得到结果后才会返回。 非阻塞调用 : 在不能立刻得到结果之前,该调用不会阻塞当前线程。 4. 为什么 JavaScript 是单线程? JavaScript 是 单线程 ,程序按照顺序排列,前面的必须处理好,后面的才会执行。 JavaScript

ES6 快速入门

坚强是说给别人听的谎言 提交于 2019-12-29 01:15:03
ES6 初识 ES6 是 ECMAScript 6.0 的简写,即 JavaScript 语言的下一代标准,已经在 2015年6月正式发布了,它的目标是让JS能够方便的开发企业级大型应用程序,因此,ES6的一些规范正在逐渐向Java、C# 等后端语言标准靠近。在 ES6 规范中,比较重大的变化有以下几个方面: 新增 let、const 命令 来声明变量,和var 相比,let 声明的变量不存在变量提升问题,但没有改变JS弱类型的特点,依然可以接受任意类型变量的声明;const 声明的变量不允许在后续逻辑中改变,提高了JS语法的严谨性。 新增解构赋值、rest 语法、箭头函数等,这些都是为了让代码看起来更简洁,而包装的语法糖。 新增模块化机制,这是 JavaScript 走向规范比较重要的一步,让前端更方便的实现工程化。 新增类和继承的概念,配合模块化,JavaScript 也可以实现高复用、高扩展的系统架构。 新增模板字符串功能,高效简洁,结束拼接字符串的时代。 新增 Promise 机制,解决异步回调多层嵌套的问题。 ES6 介绍 let和const let ES6新增了let命令,用于声明变量。其用法类似var,但是声明的变量只在let命令所在的代码块内有效。 { let x = 10; var y = 20; } x // ReferenceError: x is not

我的JS 中级学习篇

て烟熏妆下的殇ゞ 提交于 2019-12-28 14:34:53
在codefordream上进入中级学习后,感觉立马从js的基础学习往前跳了好远,上面的东西好像都是第一次看到一样.这时候才发现,说来也曾接触过js,但是这时候才发现对js的认识就停在知道两点:js中用var定义变量,用function定义函数!这时候有点羞愧了,说来真是对不起老师们的教导!之前接触js是用于编写网页,当时在dreamwever上编写网页很多功能都没有自己动手用函数实现,而是直接拖动组件等方法创建的,导致好像真的除了看到过js代码,自己还真的居然没有写过! 中级部分主要有:代码运行规则,类和对象,this引用,原型继承,和回调函数等需要学习的知识. A.关于this引用: 1.函数调用模式的时候,this指向window. 2.方法调用模式的时候,this指向方法所在的对象 3.构造函数模式的时候,this指向新生成的实例 4.apply/call调用模式的时候,this指向apply/call方法中的第一个参数 对于一个函数,我们可以通过调用该函数(注意函数也是对象)的apply方法,来将该函数内部的this引用指向一个特定对象.eg: 1 function Tool(name, usage){ 2 this.name = name; 3 this.usage = usage; 4 this.get_info = function() {console.log(

Node之文件的完整读写

无人久伴 提交于 2019-12-27 20:10:41
文件的完整读写 文件的读写需要引入node核心模块fs let fs=require('fs') readFile(filename, [options], callback)异步读取文件 fs.readFile(filename, [options], callback) 在readFile方法中,使用三个参数,其中filename参数与callback参数为必须指定的参数,options参数为可选参数。filename参数用于指定读取文件的完整文件路径及文件名,options参数值为一个对象,在其中指定读取文件时需要使用的选项,在该参数值对象中可以使用flag属性指定对该文件采取什么操作,默认值为’r’(如果指定读取的文件不存在,则抛出异常) options配置文件中flag(权限)可选值如下 ‘r’:读取文件,如果文件不存在则抛出异常。 ‘r+’:读取并写入文件,如果文件不存在则抛出异常。 ‘rs’:以同步方式读取文件并通知操作系统忽略本地文件系统缓存,如果文件不存在则抛出异常。由于该属性值的使用将使操作系统忽略本地文件系统缓存机制,因此在操作网络文件系统时建议使用该属性值,但由于其对性能产生一定的负面影响,所以在其他场合下不建议使用。 ‘w’:写入文件。如果文件不存在则创建该文件,如果该文件已存在则清空文件内容。 ‘wx’:作用与’w’类似,但是以排他方式写入文件。 ‘w+

ESP32的BLE_SPP

China☆狼群 提交于 2019-12-27 13:52:29
最近在捣鼓这个ESP32的BLE的SPP功能,把自己的心得体会写下来,如果有什么不对的地方欢迎大家来留言讨论。 首先是乐鑫官方的源码地址: https://github.com/espressif/espidf/tree/30372f5a4ff2c0dfdaad95f544dc36bcdda30b75/examples/bluetooth/bluedroid/ble/ble_spp_server 这个模式的蓝牙是低功耗蓝牙串口传输,它的工作流程是: 1、初始化蓝牙控制器 ret = esp_bt_controller_init(&bt_cfg); 然后使能蓝牙控制器 ret = esp_bt_controller_enable(ESP_BT_MODE_BLE); 这个ESP_BTMODE_BLE是使能的模式选择,可以是BLE也可以是BT还可以是两者的共存。 2、初始化蓝牙堆栈 ret = esp_bluedroid_init(); 并使能堆栈 ret = esp_bluedroid_enable(); 经过以上两个步骤,蓝牙就已经初始化完成了,是不是很简单。 接下来就是一些回调函数了, 这个是GATT的注册回调函数 esp_ble_gatts_register_callback(gatts_event_handler); 这个是GAP的注册回调函数 esp_ble_gap

同源策略和跨域解决方案

浪尽此生 提交于 2019-12-27 06:30:06
同源策略和跨域解决方案 同源策略 一个源的定义 如果两个页面的协议,端口(如果有指定)和域名都相同,则两个页面具有相同的 源 。 举个例子: 下表给出了相对http://a.xyz.com/dir/page.html同源检测的示例: URL 结果 原因 http://a.xyz.com/dir2/other.html 成功 http://a.xyz.com/dir/inner/another.html 成功 https://a.xyz.com/secure.html 失败 不同协议 ( https和http ) http://a.xyz.com:81/dir/etc.html 失败 不同端口 ( 81和80) http://a.opq.com/dir/other.html 失败 不同域名 ( xyz和opq) 同源策略是什么 同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。所以xyz.com下的js脚本采用ajax读取abc.com里面的文件数据是会被拒绝的。 同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。 不受同源策略限制的 1. 页面中的链接,重定向以及表单提交是不会受到同源策略限制的。 2. 跨域资源的引入是可以的。但是js不能读写加载的内容。如嵌入到页面中的