浅谈JS异步(asychrouous)
一、概念
(1)asychronous 异步
是JS这种单线程语言解决多任务的一种方法,将耗时的任务(io)设定为异步工作,先交给浏览器负责相关功能的线程来实现耗时的部分工作,按顺序放入任务队列中,等待主代码执行完成,而主线程继续下一个任务,不阻塞代码;主线程任务完成后,会收到浏览器的通知,来实现异步任务的其他代码执行
===>事件循环+任务队列
(2)sychronous 同步
任务的执行是一个接着一个执行的,上一个任务执行完成才能继续下一个任务,有多个窗口,进行一个接一个的执行任务
二、异步有序问题
1、回调=====>回调地狱
当我们需要进行有序任务时,最粗暴的方式就是用时间函数嵌套,少个还可以分辨,但若出现上百、上千个事件呢?如果任然使用这种方法,就会形成“回调地狱”,没有办法阅读处时间函数的时间对应的代码是哪一个,不利于后续的维护:
setTimeout(function () {
console.log("a");
setTimeout(function () {
console.log("b");
setTimeout(function () {
console.log("c");
setTimeout(function () {
console.log("d");
}, 1000)
}, 2000)
}, 1000)
}, 1000)
于是乎,我们的先人们捣鼓出了专门处理异步的方法。
2、Promise 构造函数
首先,我们来看一看使用Promise 构造函数与上面的代码有什么不同
new Promise(function (resolve, reject) {
// console.log("a1");
setTimeout(function () {
console.log("a");
resolve();
}, 1000)
}).then(() => {
// return 1;//下一个then被处罚时可以接收返回值
return new Promise(function (resolve, reject) {
// console.log("b1");
setTimeout(function () {
console.log("b");
resolve();
}, 2000)
})
}).then((data) => {
return new Promise(function (resolve, reject) {
// console.log("c1");
setTimeout(function () {
console.log("c",data);
resolve();
},3000)
})
})
我们可以看到,Promise让每一个异步都是平行的了,不再是嵌套关系,语义化非常强,让人一眼可以看出每个事件发生的顺序。
(1)使用Promise要注意状态值:
- pending 已就绪, Promise实例化的同时就已就绪,状态只可改变1次,且不可逆
- resolved/fulfilled 已完成
- rejected 已失败
===>状态改变,then方法会触发onfulfilled,onrejected事件
(2)Promise构造函数
我们分步骤来看,是怎样应用的:
new Promise(function(resolve,reject){});
let fn1;
let fn2;
new Promise(function(resolve,reject){//两个形参,都是回调函数
resolve();
fn1 = resolve;
fn2 = reject;
});
resolve()方法会返回已完成状态,就会触发onfulfilled事件,让then()代码走下去
若要写异步函数,则将第一个异步函数写在Promise里面,之后每一个任务可以使用then()来触发,每个then()只能完成一个任务
p.then((data)=>{//参数为2个事件监听器,第一个是已成功时触发,第二个是以失败时触发
console.log("onfulfilled",data);
},(data)=>{
console.log("onrejected",data);//onrejected 触发且异常,不报错
})
console.log(p);
then :
- 返回值为promise对象,初始状态是pending
- 监听器被触发,监听函数执行完成后,返回值的状态发生改变
- 改变的情况由监听函数的执行返回值决定,而具体情况参照Promise.resolve(返回值)
then(onfulfilled,onrejected)含有两个参数,都是事件监听器(函数),第一个是已成功时触发,第二个是以失败时触发。onrejected 触发且异常时,不报错。
整体的代码就是:
let fn1;
let fn2;
let p = new Promise(function(resolve,reject){//两个形参,都是回调函数
resolve();
//第一个异步函数放在Promise里
fn1 = resolve;
fn2 = reject;
}); p.then((data)=>{//参数为2个事件监听器,第一个是已成功时触发,第二个是以失败时触发
console.log("onfulfilled",data); },(data)=>{
console.log("onrejected",data);//onrejected 触发且异常,不报错
}) console.log(p);
(3)all(),race()
在Promise中有两个好用的方法,就是 all(),race()
- all()方法:在所有异步代码都跑了后,同时输出结果,但结果显示顺序根据异步事件结束的先后来的
let p1 = new Promise(function (resolve, reject) {
console.log("a开始了");
setTimeout(function () {
console.log("a");
resolve();
}, 4000)
})
let p2 = new Promise(function (resolve, reject) {
console.log("b开始了");
setTimeout(function () {
console.log("b");
resolve();
}, 3500)
})
let p3 = new Promise(function (resolve, reject) {
console.log("c开始了");
setTimeout(function () {
console.log("c");
resolve();
}, 5000)
})
let pp = Promise.all([p1,p2,p3]);
pp.then(()=>{
console.log("all");
})

- race()方法:赛跑,谁先结束谁先输出
let p1 = new Promise(function (resolve, reject) {
console.log("a开始了");
setTimeout(function () {
console.log("a");
resolve();
}, 4000)
})
let p2 = new Promise(function (resolve, reject) {
console.log("b开始了");
setTimeout(function () {
console.log("b");
resolve();
}, 3500)
})
let p3 = new Promise(function (resolve, reject) {
console.log("c开始了");
setTimeout(function () {
console.log("c");
resolve();
}, 5000)
})
// let pp = Promise.all([p1,p2,p3]);
// pp.then(()=>{
// console.log("all");
// })
pp = Promise.race([p1,p2,p3]);
pp.then(()=>{
console.log("race");
})

b时间最短,因此是b获胜
all、race 都生成promise对象,但是状态的变化情况不一样
(4)返回值 return
Promise.value 通过resolve传递的参数
Promise.reslove(value)方法,返回一个以给定值解析后的Promise对象
value有三种情况:
- 普通值:除了promise对象,和thenable对象的所有值,生成一个已完成的promise对象并且PromiseValue的值就是传入的value
- promise对象,直接返回该value
- thenable对象,参照new Promise 生成的promise对象,其中then方法就好比new Promise(cb)中的cb
在then(data)中,data就是value的值,我们回到开头的那段代码:
new Promise(function (resolve, reject) {
// console.log("a1");
setTimeout(function () {
console.log("a");
resolve();
}, 1000)
}).then(() => {
// return 1;//下一个then被处罚时可以接收返回值
return new Promise(function (resolve, reject) {
// console.log("b1");
setTimeout(function () {
console.log("b");
resolve();
}, 2000)
})
}).then((data) => {
return new Promise(function (resolve, reject) {
// console.log("c1");
setTimeout(function () {
console.log("c",data);
resolve();
},3000)
})
})
then(() => {
// return 1;//下一个then被处罚时可以接收返回值,大家可以自己去试一试。
浅谈JS异步(asychrouous)的更多相关文章
- 浅谈JS异步轮询和单线程机制
单线程特点执行异步操作 js是单线程语言,浏览器只分配给js一个主线程,用来执行任务(函数),但一次只能执行一个任务,这些任务就会排队形成一个任务队列排队等候执行.一般而已,相对耗时的操作是要通过异步 ...
- 浅谈js异步
大家都知道,js是一个单线程的语言(只有一个线程来执行js函数),所以如果某一个函数执行任务耗时比较长的话,就会造成阻塞,使得后续任务一直处于等待状态. 一.阻塞示例 function f1(){ ; ...
- 浅谈JS之AJAX
0x00:什么是Ajax? Ajax是Asynchronous Javascript And Xml 的缩写(异步javascript及xml),Ajax是使用javascript在浏览器后台操作HT ...
- 浅谈JS中的闭包
浅谈JS中的闭包 在介绍闭包之前,我先介绍点JS的基础知识,下面的基础知识会充分的帮助你理解闭包.那么接下来先看下变量的作用域. 变量的作用域 变量共有两种,一种为全局变量,一种为局部变量.那么全局变 ...
- 浅谈 js 正则字面量 与 new RegExp 执行效率
原文:浅谈 js 正则字面量 与 new RegExp 执行效率 前几天谈了正则匹配 js 字符串的问题:<js 正则学习小记之匹配字符串> 和 <js 正则学习小记之匹配字符串优化 ...
- 浅谈 js 字符串之神奇的转义
原文:浅谈 js 字符串之神奇的转义 字符串在js里是非常常用的,但是你真的了解它么?翻阅<MDN String>就可以了解它的常见用法了,开门见山的就让你了解了字符串是怎么回事. 'st ...
- 浅谈 js 正则之 test 方法
原文:浅谈 js 正则之 test 方法 其实我很少用这个,所以之前一直没注意这个问题,自从落叶那厮写了个变态的测试我才去看了下这东西.先来看个东西吧. var re = /\d/; console. ...
- 浅谈 js 数字格式类型
原文:浅谈 js 数字格式类型 很多人也许只知道 ,123.456,0xff 之类的数字格式.其实 js 格式还有很多数字格式类型,比如 1., .1 这样的,也有 .1e2 这样的. 可能有人说这是 ...
- 浅谈 js 语句块与标签
原文:浅谈 js 语句块与标签 语句块是什么?其实就是用 {} 包裹的一些js代码而已,当然语句块不能独立作用域.可以详细参见这里<MDN block> 也许很多人第一印象 {} 不是对象 ...
随机推荐
- Java虚拟机理解-内存管理
运行时数据区域 jdk 1.8之前与之后的内存模型有差异,方法区有变化(https://cloud.tencent.com/developer/article/1470519). java的内存数据区 ...
- python 下载bilibili视频
说明: 1.清晰度的选择要登录,暂时还没做,目前下载的视频清晰度都是默认的480P 2.进度条仿linux的,参考了一些博客修改了下,侵删 3.其他评论,弹幕之类的相关爬虫代码放在了https://g ...
- 闲着没事,做个chrome浏览器插件,适合初学者
时光偷走的,永远都是我们眼皮底下看不见的珍贵. 本插件功能:替换掉网页中的指定图片的src地址. 使用插件前: 使用插件后: 鲜花(闲话):这个网站的不加水印的图片连接被保存在,图片的data-ima ...
- springboot 简单邮件发送
写作原因: 项目接近尾声,需求一变再变,其实技术点从未改变,只是业务逻辑的变更,发送邮件提醒的功能,两个月变更七次.我想把技术点记录下来,这里无关乎业务,只有发送邮件的功能. 邮件发送准备说明: 由于 ...
- 前端——BOM与DOM
目录 前戏 window对象 window的子对象 navigator对象(了解即可) screen对象(了解即可) history对象(了解即可) location对象 弹出框 计时相关 DOM H ...
- webhook功能概述
1.什么是webhook? webhooks是一个api概念,是微服务api的使用范式之一,也被成为反向api,即:前端不主动发送请求,完全由后端推送. 举个常用例子,比如你的好友发了一条朋友圈,后端 ...
- rest_framework框架下的Django声明和生命周期
rest_framework框架下的Django声明和生命周期 Django声明周期(request) 客户端发起请求 请求经过wsgi wsgi: 是一个协议----web服务网关接口,即在web服 ...
- Vue-cli2.0
本文的学习来自技术胖大神的教程:https://jspang.com/ Vue-cli是vue官方出品的快速构建单页应用的脚手架 开发一个项目,在开始的时候,会构建项目结构.webpack.怎么运行. ...
- vc++调用msscript.ocx解析实现C++与JavaScript脚本交互
ScriptControl接口 属性名称 类型 备注 AllowUI BOOL 检测是否允许运行用户的接口元素.如果为False,则诸如消息框之类的界面元素不可见. CodeObject Object ...
- MySQL基础篇(04):存储过程和视图,用法和特性详解
本文源码:GitHub·点这里 || GitEE·点这里 一.存储过程 1.概念简介 存储程序是被存储在服务器中的组合SQL语句,经编译创建并保存在数据库中,用户可通过存储过程的名字调用执行.存储过程 ...