一、概念

(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){});
//两个形参: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有三种情况:

  1. 普通值:除了promise对象,和thenable对象的所有值,生成一个已完成的promise对象并且PromiseValue的值就是传入的value
  2. promise对象,直接返回该value
  3. 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)的更多相关文章

  1. 浅谈JS异步轮询和单线程机制

    单线程特点执行异步操作 js是单线程语言,浏览器只分配给js一个主线程,用来执行任务(函数),但一次只能执行一个任务,这些任务就会排队形成一个任务队列排队等候执行.一般而已,相对耗时的操作是要通过异步 ...

  2. 浅谈js异步

    大家都知道,js是一个单线程的语言(只有一个线程来执行js函数),所以如果某一个函数执行任务耗时比较长的话,就会造成阻塞,使得后续任务一直处于等待状态. 一.阻塞示例 function f1(){ ; ...

  3. 浅谈JS之AJAX

    0x00:什么是Ajax? Ajax是Asynchronous Javascript And Xml 的缩写(异步javascript及xml),Ajax是使用javascript在浏览器后台操作HT ...

  4. 浅谈JS中的闭包

    浅谈JS中的闭包 在介绍闭包之前,我先介绍点JS的基础知识,下面的基础知识会充分的帮助你理解闭包.那么接下来先看下变量的作用域. 变量的作用域 变量共有两种,一种为全局变量,一种为局部变量.那么全局变 ...

  5. 浅谈 js 正则字面量 与 new RegExp 执行效率

    原文:浅谈 js 正则字面量 与 new RegExp 执行效率 前几天谈了正则匹配 js 字符串的问题:<js 正则学习小记之匹配字符串> 和 <js 正则学习小记之匹配字符串优化 ...

  6. 浅谈 js 字符串之神奇的转义

    原文:浅谈 js 字符串之神奇的转义 字符串在js里是非常常用的,但是你真的了解它么?翻阅<MDN String>就可以了解它的常见用法了,开门见山的就让你了解了字符串是怎么回事. 'st ...

  7. 浅谈 js 正则之 test 方法

    原文:浅谈 js 正则之 test 方法 其实我很少用这个,所以之前一直没注意这个问题,自从落叶那厮写了个变态的测试我才去看了下这东西.先来看个东西吧. var re = /\d/; console. ...

  8. 浅谈 js 数字格式类型

    原文:浅谈 js 数字格式类型 很多人也许只知道 ,123.456,0xff 之类的数字格式.其实 js 格式还有很多数字格式类型,比如 1., .1 这样的,也有 .1e2 这样的. 可能有人说这是 ...

  9. 浅谈 js 语句块与标签

    原文:浅谈 js 语句块与标签 语句块是什么?其实就是用 {} 包裹的一些js代码而已,当然语句块不能独立作用域.可以详细参见这里<MDN block> 也许很多人第一印象 {} 不是对象 ...

随机推荐

  1. tjoi2019题解

    t1:矩阵快速幂 t2:裸的平衡树 splay比treap代码长太多 常数大一倍 没加输优直接t了 还要特判n=1(我的splay删除的时候会遇到问题) t3: 很显然是容斥 然后对于$A+B+C+D ...

  2. Unable to preventDefault inside passive event listener due to target being treated as passive 怎么办?

    本篇为转载,原文链接:https://blog.csdn.net/lijingshan34/article/details/88350456 翻译一下:chrome 监听touch类事件报错:无法被动 ...

  3. To learns

    1. avro https://www.jianshu.com/p/ecbb607809c4

  4. 在加权无向图上求出一条从1号结点到N号结点的路径,使路径上第K+1大的边权尽量小

    二分+最短路算法 #include<cstdio> #include<iostream> #include<cstring> #include<algorit ...

  5. Web基础了解版11-Ajax-JSON

    Ajax AJAX即“Asynchronous Javascript And XML”:是,不发生页面跳转.异步请求载入内容并改写局部页面内容的技术. 也可以简单的理解为通过JS向服务器发送请求.   ...

  6. Javascript用途,语法特点,难点,调试工具,引入方式,命名规范,变量声明及赋值,数据类型,运算符

    JavaScript用来干什么 数据的验证 将动态的内容写入到网页当中(ajax) 对事件做出相应 读写html当中的内容 检测浏览器 创建cookies 模拟动画 语法特点 基于对象和事件驱动的松散 ...

  7. shiro整合springmvc

    说明   代码及部分相关资料根据慕课网Mark老师的视频进行整理   其他资料: shiro官网 流程 配置 1) 配置web.xml整合shiro 把shiro整合到springMVC实质上是在we ...

  8. xshell连接kali linux虚拟机

    这次测试一波三折 刚开始在百度经验看的先修改ssh参数,蓝色的字是百度的,重点都在图片上 1.修改sshd_config文件,命令为: vi /etc/ssh/sshd_config 将#Passwo ...

  9. 《图解机器学习-杉山将著》读书笔记---CH3

    CH3 最小二乘学习法 重点提炼 提出最小二乘学习法的缘故: 最小二乘学习法公式 对不同模型进行最小二乘法学习,得到最小二乘公式中的参数theta: 1.线性模型   代入3.1公式,对参数求偏导,偏 ...

  10. SQL Server2012高可用之日志传送测试

    (一)日志传送架构 (1.1)相关服务器 主服务器   :用于生产的服务器,上面运行这生产SQL Server数据库: 辅助服务器:用于存放主服务器上数据库的一个“镜像”数据库: 监控服务器:用来监控 ...