Promise 学习笔记
一、Promise 简介
Promise 是 JS 中进行异步编程的新解决方案。(旧方案是单纯使用回调函数)
优点:
- 指定回调函数更加灵活
- 支持链式调用,可以解决毁回调地狱问题
二、Promise 初体验
resolve、reject 两者都是函数类型的数据,分别为成功和失败后的回调。
在内部封装时可以携带参数。
const p = new Promise((resolve, reject) => { setTimeout(() => { if (xxx) { resolve(arg1); //将 promise 对象的状态设置为成功 } else { reject(arg2); //将 promise 对象的状态设置为失败 } }, 1000)})
// 第一个为成功回调,第二个为失败回调p.then((arg) => { alert('success, the arg is ' + arg);}, (arg) => { alert('failed' + arg);}) 实际使用中也可以这样封装:
function asyncTask(arg) { return new Promise((resolve, reject) => { if (xxx) { resolve(); } else { reject(); } })}
const obj = asyncTask(xxx);obj.then((arg1) => { ...}, (arg2) => { ...}) util.promisify 方法:
// 可以借助 node.js 的该方法来将函数转化为 promise 风格const util = require('util');const fs = require('fs');
let mineReadFile = util.promisify(fs.readFile);mineReadFile(...).then(...);三、Promise 状态与值
指实例对象中的一个属性:PromiseState
只有以下两种转变情况:
pending -> fulfilled
pending ->rejected
且一个 promise 对象只能改变一次状态。无论变为成功还是失败,都会有一个结果数据。成功的结果数据一般称为 value,失败的结果数据一般称为 reason。
Promise 对象的值:
实例对象中的另一个属性 PromiseResult,保存着对象成功/失败的结果
四、Promise 的基本流程

五、Promise API
1、构造函数
executor = (resolve, reject) => {};Promise(excutor) {}; 注:executor 函数会在 Promise 内部立即同步调用,异步操作在执行器中执行。
2、Promise.prototype.then()
Promise.prototype.then(onResolved,onRejected) => {};onResolved函数:成功的回调函数onRejected函数:失败的回调函数
注:指定用于得到成功 value 的成功回调和用于得到失败 reason 的失败回调,返回一个新的 promise 对象
3、Promise.prototype.catch()
Promise.prototype.catch(reason => {}); 只用于指定失败的回调。
4、Promise.resolve()
var obj = Promise.resolve(arg); 如果传入的是非 Promise 对象,则返回结果为成功 Promise 对象。
如果传入的是 Promise 对象,参数的结果决定了 resolve 的结果。
如下方返回一个成功 Promise 对象:
let p1 = Promise.resolve(new Promise((resolve, reject) => { // resolve('It\' OK.'); reject('Error');}))console.log(p1);// catchp1.catch(reason => { console.log(reason);})5、Promise.reject()
var obj = Promise.reject(arg); 传入任何类型值,返回都为失败 Promise 对象,而失败的结果是传递的值或对象。
如下方返回一个失败 Promise 对象:
let p2 = Promise.resolve(new Promise((resolve, reject) => { resolve('It\' OK.');}))console.log(p2);6、Promise.all()
Promise.all((promises) => {}) 说明:返回一个新的 promise,只有所有的 promise 都成功才成功,只要有一个失败了就直接失败。
成功返回结果是所有 promise 对象返回结果的数组,
失败返回结果是失败 promise 对象的返回结果。
7、Promise.race()
Promise.race((promises) => {}) 说明:返回一个新的 promise,第一个完成(改变状态)的 promise 的结果状态就是最终的结果状态。
六、Promise 关键问题
1、Promise 状态改变的方法
- resolve(value):如果当前是 pending 就会变为 resolved
- reject(reason):如果当前是 pending 就会变为 rejected
- 抛出异常:如果当前是 pending 就会变为 rejected
let p = new Promsie((resolve, reject) => { // resolve resolve('OK'); // reject reject('error'); // throw exception throw "Exception!";})2、指定多个成功/失败回调
一个 Promise 指定多个成功/失败回调,当promise改变为对应状态时都会调用。
let p = new Promise((resolve, reject) => { resolve('OK');})p.then(value => { console.log(value+'!');})p.then(value => { console.log(value+'!!');})3、改变状态与指定回调谁先谁后
都有可能。但一般执行器内是异步任务,因此一般是先指定回调。
若要先改变状态:
- 执行器内直接改变状态
- 延迟更长时间再调用
then()
得到数据的时间:
- 如果先指定的回调,那当状态发生改变时,回调函数就会调用,得到数据。
- 如果先改变的状态,那当指定回调时,回调函数就会调用,得到数据。
4、then() 方法返回结果
主要有三种情况:
let res = p.then(value => { // 1. throw exception,那么失败,结果是异常 throw 'An exception!'; // 2. 返回结果是非 Promise 对象,那么成功,结果是该值 return 521; // 3. 返回结果是 Promise 对象,那么成功和返回值都由该对象决定 return new Promise((resolve, reject) => { // resolve('OK'); reject('error'); })})5、Promise 串联任务
比如串联两个异步任务与一个同步任务:
let p = new Promise((resolve, reject) => { // 第一个异步 Promise setTimeout(() => { resolve('First OK'); }, 1000);}).then(value => { // 成功后告知第一个异步 Promise 完成,输出 'First OK' console.log(value); // 回调第二个异步 Promise return new Promise((resolve, reject) => { setTimeout(() => { resolve('Second OK'); }, 2000); })}).then(value => { // 成功后告知第二个异步 Promise 完成,输出 'Second OK' console.log(value); // 该回调返回成功 Promise}).then(value => { // 第三个 Promise 回调开始,输出 undefined console.log(value);})6、Promise 异常穿透
Promise 链中任意层的失败可以穿透至最后层,而被捕获的现象。
如:
// 中间任意层可以不指定失败捕获new Promise((resolve, reject) => { setTimeout(() => { resolve('OK'); }, 1000);}).then(value => { throw 'Second layer exception!';}).then(value => { console.log(3);}).then(value => { console.log(4);}).catch(reason => { console.err(reason);})7、中断 Promise 链
有且只有一个方法:返回一个 pending 状态的 Promise 对象。
....then(value => { ... return new Promise(() => {});})...七、async 与 await
1、async 函数
async 函数的返回值为 Promise 对象,且其结果同样由函数执行的返回值决定。
2、await 表达式
- await 右侧的表达式一般为 promise 对象,但也可以是其它的值
- 如果表达式是 promise 对象,await 返回的是 promise 成功的值
- 如果表达式是其它值,直接将此值作为 await 的返回值
注:
- await 必须写在 async 函数中,但 async 函数中可以没有 await
- 如果 await 的 Promise 失败了,就会抛出异常,需要捕获
3、结合使用的例子
异步依次读取文件:
const fs = require('fs');const util = require('util');const mineReadFile = util.promisify(fs.readFile)
!async function main() { try { let data1 = await mineReadFile('./1.txt'); let data2 = await mineReadFile('./2.txt'); let data3 = await mineReadFile('./3.txt'); console.log(data1 + data2 + data3); } catch(e) { console.warn(e); }}();如果这篇文章对你有帮助,欢迎分享给更多人!
部分信息可能已经过时