javaScript异步编程--笔记

1、异步编程–单线程

JS执行环境中负责执行代码的线程只有一个,排队等待执行。
特点总结如下:

  • 同步模式与异步模式
  • 事件循环与消息队列
  • 异步编程的几种方式
  • Promise 异步方案、宏任务/微任务队列
  • Generator异步方案、Async/Await语法糖

2、同步模式

大多数是同步执行,并不是同时执行,而是排队,按顺序执行。
javaScript异步编程--笔记_第1张图片
缺点,如果耗时比较长的话,会造成阻塞,会出现卡死的现象。

3、异步模式

不会去等待这个任务的结束才开始下一个任务。
难点,代码的执行顺序混乱。
消息队列,逐步执行
javaScript异步编程--笔记_第2张图片
执行顺序图
javaScript异步编程--笔记_第3张图片
备注:js是单线程的,但浏览器不是单线程的。有一个线程去监控倒计时,当倒计时结束之后,负责把这个任务放入消息队列。

4、回调函数

所有异步编程方案的根基。
由调用者定义,交给执行者执行的函数。
javaScript异步编程--笔记_第4张图片

5、Promise概述

原始的回调地狱问题
javaScript异步编程--笔记_第5张图片
javaScript异步编程--笔记_第6张图片

6、Promise基本用法

const promise = new Promise(function(resolve,reject){
     
	//这里用于 兑现 承诺
	resolve(100);//承诺达成
	//reject(new Error('promise rejected'));// 承诺失败
});
promise.then(function(val){
     
	console.log('resolved',val);
},function(error){
     
	console.log('rejected',error);
});
console.log('end');//end先输出,因为即使Promise里边没有时间延迟,但也需要放进消息队列执行,所以end先输出

7、Promise使用案例

function ajax(url){
     
	return new Promise(function(resolve,reject){
     
		var xhr = new XMLHttpRequest();
		xhr.open('GET',url);
		xhr.responseType = 'json';
		xhr.onload = function(){
     
			if( this.status == 200 ){
     
				resolve(this.response);
			}else{
     
				reject(new Error(this.statusText));
			}
		};
		xhr.send();
	})
}
ajax('/api/user.json').then(function(res){
     
	console.log(res);
},function(error){
     
	console.log(error);
})

8、Promise链式调用

then方法之后返回的也是一个promise对象。
每一个then方法实际上都是在为上一个then返回的promise对象添加状态明确之后的回调。
依次执行。
javaScript异步编程--笔记_第7张图片
使用链式调用去代替之前的回调嵌套。
总结:

  • Promise对象的then方法会返回一个全新的Promise对象
  • 后面的then方法就是在为上一个then返回的Promise注册回调
  • 前面then方法中回调函数的返回值会作为后面then方法回调的参数
  • 如果回调中返回的是Promise,那后面then方法的回调会等待它的结束

9、Promise异常处理

function ajax(url){
     
	return new Promise(function(resolve,reject){
     
		var xhr = new XMLHttpRequest();
		xhr.open('GET',url);
		xhr.responseType = 'json';
		xhr.onload = function(){
     
			if( this.status == 200 ){
     
				resolve(this.response);
			}else{
     
				reject(new Error(this.statusText));
			}
		};
		xhr.send();
	})
}
// 异常或者失败,用catch方法捕获错误
ajax('/api/user.json').then(function(res){
     
	console.log(res);
}).catch(function(err){
     
	console.log(err);
})

在全局对象中注册,捕获Promise错误。
浏览器环境:

window.addEventListener('unhandledrejection',event=>{
     
	const {
      reason,promise } = event;
	console.log(reason,promise);
	// reason Promise失败原因,一般是一个错误对象
	// promise 出现异常的Promise对象
	
	event.preventDefault();
},false);

node环境下:
javaScript异步编程--笔记_第8张图片
最好的做法是,在代码中明确捕获每一个可能的异常

10、Promise静态方法

// Promise.resolve()
Promise.resolve('foo') //将字符串转换为Promise对象
.then(function(val){
     
	console.log(val);//foo。
});
// 传入一个含有then方法的对象,转换为Promise,常用于Promise之前出现的库,转换为现在的Promise
Promise.resolve({
     
	then:function(onFulfilled,onRejected){
     
		onFulfilled('foo')
	}
})
.then(function(val){
     
	console.log(val);//foo。
});
//Promise.reject();
Promise.reject(new Error('rejected'))
.catch(function(err){
     
	console.log(err);
})

11、Promise并行执行

Promise.all();
只有当里边任务全部完成, 才会成功结束
javaScript异步编程--笔记_第9张图片
promise.race();
只会等待第一个结束的任务
javaScript异步编程--笔记_第10张图片

12、Promise执行时序

回调队列中的任务称之为 宏任务
宏任务执行过程中可以临时加上一些额外需求
可以选择作为一个新的宏任务进到队列中排队
也可以作为当前任务的 微任务
直接在当然任务结束过后立即执行
Promise的回调会作为微任务执行。
微任务的作用,提高整体的响应能力。
绝大多数异步调用会作为宏任务进行调用
特殊的:
Promise & MutationObserver 作为微任务
nodejs里边的 process.nextTick 。

举例:
一个人去银行柜台办理存款业务。办理完存款业务之后。你又想办理信用卡。一般情况下,为了提供工作效率,业务员会顺带帮你一块办理。这就是宏任务里边的微任务。
程序也一样,为了提高执行效率,才有了微任务。

13、Generator 异步方案

javaScript异步编程--笔记_第11张图片
Generator配合 Promise 的异步方案
javaScript异步编程--笔记_第12张图片
执行递归
javaScript异步编程--笔记_第13张图片
try catch获取错误
javaScript异步编程--笔记_第14张图片
github: https://github.com/tj/co

14、Async /Await 语法糖

语言层面的异步编程标准。内部执行顺序,从上往下。不需要再配合CO这样的执行器
await 只能出现在 async 函数的内部
javaScript异步编程--笔记_第15张图片

你可能感兴趣的:(javascript)