Promise,async,await

1.并发,并行,异步,同步

1.1并发,并行

并发:对于单核处理器来说,计算机通过分配时间片的形式,让一个任务执行一段时间后执行另一个任务,不同任务会交替往复的进行。(这个过程也被称为进程或者线程的上下文切换
请添加图片描述

并行:对于多核处理器来说,计算机能够在不同的核心上并行的执行任务。
请添加图片描述

1.2同步,异步

同步和异步是两种不同的编程方式。
同步:必须在前一个任务完成之后,才能执行下一个任务,所以在同步中没有并发和并行的概念。

请添加图片描述
异步:不同的任务之间不会相互等待,在执行任务1时可以同时执行任务2,可通过多线程编程实现,每个线程会被分配到不同的核心上执行,实现真正的并行。但如果计算机为单核处理器,操作系统则会通过分配时间片的方式并发执行这些线程。

2.js单线程异步编程

异步编程:允许我们在执行一个长时间任务时,程序不需要进行等待,而是继续执行之后的代码,知道这个任务完成之后在通知你,形式通常为回调函数。
js是没有多线程概念的,但是可以通过函数回调机制实现单线程的并发,当回调函数需要被执行时,会先执行回调函数,通过这种异步编程的方式实现单线程的并发。
优点:避免程序阻塞,提高CPU的执行效率

请添加图片描述

对于I/O密集的程序(WEB应用)会经常执行网络操作数据库访问,这类应用适合
异步编程。如果用多线程容易浪费资源,因为每个线程的大多数时间都是在等待I/O操作,线程自身也会占用内存,线程的切换也有额外开销,线程之间还有资源竞争问题。
多线程编程适合于计算量密集的应用(视频图像处理,科学计算),尽可能让每一个核心发挥最大功效

3.Promise

当需要依次执行多个异步操作时,我们我们需要嵌套回调函数,导致“回调地狱”,代码可读性差。
使用Promise可以用链式结构将多个异步操作串联起来。在链式结构的后面加上.catch方法可以接受,链式中任意个promise的错误,.finally方法可以在promise结束后做一些清理工作。

4.async,await

async与await是ECMA17新加入的语法糖,可以让异步操作更加简单明了。
首先用async将一个函数标记为异步函数,在异步函数中我们可以调用其他的异步函数,使用await接收promise完成后返回的结果。awati不会暂停程序执行,它的底层是通过Promise和事件循环实现的。

5.await使用时的陷阱

陷阱1

async function f(){
	const a = await fetch('http://...post1);
	const b = await fetch('http://...post2);

	//修改
	const promiseA = fetch('http://...post1);
	const promiseB = fetch('http://...post2);
	const [a,b] = await Promise.all([promiseA,promiseB]);

这样的写法,会打破两个fetch的并行,需等到第一个任务完成后才开始执行第二个任务,我们可以用.all将promise组合起来,然后再用await,这样程序的运行效率能够提升一倍.

陷阱2

async function f() {
  [1, 2, 3].forEach(async (i) => {
    await someAsyncOperation();
  })
}

//修改
const promises = [
  someAsyncOperation(),
  someAsyncOperation(),
  someAsyncOperation(),
];

for await (let result of promises) {
  //...
}

f();

在循环中使用异步操作是不能使用forEach或者map这一类方法的,如上面代码中,forEach会立刻返回,不会等到所有异步操作都执行完毕。可以使用传统的for循环解决。

陷阱3

不能在全局或普通函数中使用await,其只能被使用在异步函数中(async function

6.promise常见的API

6.1 Promise构造函数:Promise(excutor){}

excutor函数:同步执行 (resolve, reject) => {}
resolve函数:内部定义成功时我们调用的函数 value =>{}
reject函数:内部定义失败时我们调用的函数 reason => {}
说明:excutor会在Promise内部立即同步回调,异步操作在执行器中执行

6.2 Promise.prototype.then方法:(onResolved, onRejected) => {}

onResolved函数:成功的回调函数 (value)=> {}
onRejected函数:失败的回调函数(reason) => {}
说明:指定用于得到成功value的成功回调和用于得到失败reason的失败回调
返回一个新的promise对象

6.3 Promise.prototype.catch方法:(onRejected) => {}

onRejected函数:失败的回调函数(reason)=>{}
说明:then()的语法糖,相当于:then(undefined,onRejected)

6.4 Promise.resolve方法:(value)=> {}

value:成功的数据或promise对象
说明:返回一个成功/失败的promise对象

6.5 Promise.reject方法:(reason) => {}

reason:失败的原因
说明:返回一个失败的promise对象

6.6 Promise.all(iterable)方法:(promises) =>{}

promises:包含n个promise的数组
说明:这个方法返回一个新的promise对象,该promise对象在iterable参数对象里所有的promise对象都成功的时候才会触发成功,一旦有任何一个iterable里面的promise对象失败则立即触发该promise对象的失败。这个新的promise对象在触发成功状态以后,会把一个包含iterable里所有promise返回值的数组作为成功回调的返回值,顺序跟iterable的顺序保持一致;如果这个新的promise对象触发了失败状态,它会把iterable里第一个触发失败的promise对象的错误信息作为它的失败错误信息。Promise.all方法常被用于处理多个promise对象的状态集合。

6.7 Promise.race方法:(promises)=> {}

promises:包含n个promise的数组
说明:返回一个新的promise,第一个完成的promise的结果状态就是最终的结果状态
看起来race方法似乎没什么特别的用处,但在处理Web服务器中的超时逻辑时却十分方便,例如我们为一个 Promise(可能是一个数据库操作)定义了100ms 的执行时限,如果耗时超过这个时间就返回一个超时错误,在这种情况下就可以考虑使用race方法。

  • 11
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值