promise/async/await

Posted web半晨

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了promise/async/await相关的知识,希望对你有一定的参考价值。

目录


1、promise基础语法

1.1、概念

1、promise是用来管理异步编程的,它本身不是异步的。new promise的时候会立即执行executor函数,只不过会在executor函数中处理一个异步操作。
2、promise有三种状态,分别是:pending(初始状态)、fulfilled(成功状态)和rejected(失败状态)。
3、promise的返回值是用来记录成功的结果或者失败的原因。
4、promise的诞生是为了解决异步请求中的回调地狱问题。
5、promise是一种设计模式,ES6中提供一个javascript内置类Promise来实现这种设计模式。
6、new Promise的时候先执行executor函数,在这里开启一个异步操作的任务,此时不等待,把其放入EventQuque任务(微任务)队列中,继续执行then方法,把then方法中的两个函数存储起来,此时还不执行这两个函数。当executor函数中的异步操作结束了,基于resolve/reject控制Promise状态,从而决定执行then存储的函数中的某一个函数。
7、执行resolve或者reject函数,都可以修改promise的状态。一旦状态被改变,再执行resolve或者reject就没用了。
8、resolve或者reject的执行,不论是否放到异步操作中,都需要等待then先执行完,把方法(函数)存储起来,才会在更改状态后执行then中对应的方法。
9、then方法执行结束会返回一个新的Promise实例。new Promise出来的实例,成功或者失败,取决于executor函数执行的时候,执行的是resolve还是reject决定的,再或者executor函数执行发生异常错误,也是会把实例状态改为失败。
10、then中存储的方法执行结果决定状态,上一个then中某个方法执行的结果,决定下一个then中哪一个方法会执行。无论是成功的方法执行,还是失败的方法执行,只要执行抛出异常,都会把实例的状态改为失败。
11、方法中如果返回一个新的Promise实例,返回这个实例的结果是成功或者失败,也决定了当前实例是成功还是失败。剩下的情况基本上都是让实例变为成功状态。
12、方法返回的结果是当前实例的value值,上一个then中的方法返回的结果会传递到下一个then的方法中。
13、then中也可以只写一个或者不写函数,then(fn)/then(null, fn)。遇到一个then,要执行成功或者失败的方法,如果此方法并没有在当前then中被定义,则顺延到下一个对应的函数。
14、Promise.all(array)返回的结果是一个Promise实例,要求array数组中的每一项都是一个新的的Promise实例,Promise.all()是等待所有数组中的实例状态都为成功才会让all实例状态为成功,value是一个集合,存储着数组中每一个实例返回的结果。凡是数组中有一个实例状态为失败,all实例的状态也是失败。
15、Promise.race(array)和all不同的地方,race是赛跑,也就是array数组中不管哪一个先处理完,处理完的结果作为race实例的最终结果。
16、async和await是ES7中Promise操作的语法糖。async是让一个普通函数返回的结果变为status = resolved,并且value = return结构的Promise实例。async最主要的作用是配合await使用,因为一旦在函数中使用await ,那么当前函数必须用async修饰。await会等待当前Promise的返回结果,只有返回结果的状态是resolved情况,才会把返回结果赋值给result。await不是同步编程,是异步编程(微任务),当代码执行到await时,先把此行执行,构建一个异步的微任务,等待Promise返回结果,并且await下面的代码也都被放到任务队列中。
17、如果Promise的返回结果是失败状态,则await不会接收其返回结果,await下面的代码永远也不会继续执行,await只能处理Promise为成功状态的结果。


1.2、promise的执行方式

1.2.1、成功

let promisee = new Promise((resolve, reject) => 
	resolve('ok');
	// resolve是成功状态的函数,
	// 对应then中的第一个函数,即result
);

// 设置成功或者失败后处理的方法
promisee.then(result => 
	console.log('成功:', result); 
	// 成功: ok
, reason => 
	console.log('失败:', reason);
);

1.2.2、失败

let promisee = new Promise((resolve, reject) => 
	reject('no');
	// reject是失败状态的函数,
	// 对应then中的第二个函数,即reason
);

// 设置成功或者失败后处理的方法
promisee.then(result => 
	console.log('成功:', result);
, reason => 
	console.log('失败:', reason); 
	// 失败: no
);

1.2.3、概念中的第7条

new Promise((resolve, reject) => 
	// 第一组
	// 这里执行完 resolve 后,
	// reject 执行也没有用了,
	// 不会再改变状态了,
	// 下同。
	resolve(1);
	reject(0);
	
	// 第二组
	// reject(0);
	// resolve(1);
).then(result => 
	console.log(`成功:$result`); 
	// 成功:1
, reason => 
	console.log(`失败:$reason`);
);

1.2.4、new Promise(resolve => ).then().then()

new Promise(resolve => 
	resolve(a);
).then(result => 
	console.log(`成功:$result`);
	return Promise.reject(result);
, reason => 
	console.log(`失败:$reason`);
	// 失败:ReferenceError: a is not defined
).then(resolve => 
	// 为什么这里进入成功函数,
	// 是因为上一个进入失败函数执行没有报错,
	// 不是说上一个进入了失败函数,
	// 下一个then也进入失败函数。
	console.log(`成功:$resolve`);
	// 成功:undefined
	// 这里的value为undefined的原因是,
	// 上一个函数没有return实际的值,
	// 所有的函数如果没有return实际都会返回undefined
, reason => 
	console.log(`失败:$reason`);
);

1.2.5、Promise.resolve(1).then().then(),reject同理

Promise.resolve(1).then(result => 
	console.log('成功:', result); 
	// 成功: 1
, reason => 
    console.log('失败:', reason);
).then(result => 
    console.log('成功:', result); 
    // 成功: undefined
, reason => 
    console.log('失败:', reason);
);

1.2.6、顺延和catch

Promise.reject(10).then(result => 
	console.log(`成功:$result`);
	return result * 10
).then(null, reason => 
	// 第一个then中没有reason函数,
	// 所以这个reject执行的结果顺延到了第二个then的reason函数。
	console.log(`失败:$reason`); 
	// 失败:10
);

Promise.reject(10).then(result => 
	console.log(`成功:$result`);
	return result * 10
).then(result => 
	console.log(`成功:$result`);
).catch(reason => 
	// catch是专门捕获异常的方法,
	// 因为第一和第二个then中都没有reason函数,
	// 所以走到catch才有输出。
	console.log(`失败:$reason`); 
	// 失败:10
);

Promise.resolve(10).then(result => 
	console.log(a);
).catch(reason => 
	// 虽然executor中的resolve执行的结果是成功的,
	// 但是第一个then中的result执行的结果是失败的,
	// 所以最后catch捕获到的就是失败的结果。
	console.log(`失败:$reason`);
	// 失败:ReferenceError: a is not defined
);

1.2.7、all和race

let p1 = Promise.resolve(1);

let p2 = new Promise(resolve => 
	setTimeout(_ => 
		resolve(2);
	, 1000)
);

let p3 = Promise.reject(3);

Promise.all([p1, p2, p3]).then(result => 
	console.log(`成功:$result`);
).catch(reason => 
	console.log(`失败:$reason`); 
	// 失败:3
);

Promise.all([p2, p1]).then(result => 
	// 返回的结果是按照arr中编写实例的顺序组合在一起
	console.log(`成功:$result`); 
	// 成功:2,1
).catch(reason => 
	console.log(`失败:$reason`);
);

2、async/await的使用方式

async function fun(i) 
	let isIndex = await i == 1 ? '进行中' : '已完成';
	console.log(isIndex); 
    // fun(1); 进行中
    // fun(2); 已完成
            
	return isIndex;
;

console.log(fun(1)); 
// Promise <pending>
console.log(fun(2)); 
// Promise <pending>

以上是关于promise/async/await的主要内容,如果未能解决你的问题,请参考以下文章

promise与async和await的区别

promise/async/await

[转] Async/Await替代Promise的6个理由

JavaScript 的 Async/Await 完胜 Promise 的六

Promise,async,await

Promise,Async,await简介