MDN Promise 文档
Promise 及其作用
- ES6 内置类
- 回调天堂:AJAX 的串行和并行
Promise 的 executor 函数和状态
- executor
Promise 状态
- pending 初始状态
- fulfilled 操作胜利实现
- rejected 操作失败
Promise 中的 then 和 catch
- then(func1,func2) / then(func)
- catch(func)
- then 链机制
Promise 中其它罕用办法
- Promise.all
- Promise.race
- Promise.reject (选)
- Promise.resolve (选)
1、Promise 及其作用
1-1、ES6 内置类
Promise 的诞生就是为了解决异步申请中的回调天堂问题:它是一种设计模式,ES6 中提供了一个 JS 内置类 Promise,来实现这种设计模式
function ajax1() { return new Promise((resolve) => { $.ajax({ url: "/url1", // ... success: resolve, }); });}function ajax2() { return new Promise((resolve) => { $.ajax({ url: "/url2", // ... success: resolve, }); });}function ajax3() { return new Promise((resolve) => { $.ajax({ url: "/url3", // ... success: resolve, }); });}ajax1() .then((result) => { return ajax2(result.map((item) => item.id)); }) .then((result) => { return ajax3(); }) .then((result) => {});
1-2、回调天堂:AJAX 的串行和并行
回调天堂:上一个回调函数中持续做事件,而且持续回调(在实在我的项目的 AJAX 申请中经常出现回调天堂)=> 异步申请、不不便代码的保护
2、Promise 的 executor 函数和状态
2-1、executor
new Promise([executor]) ,[executor]执行函数是必须传递的
Promise 是用来治理异步编程的,它自身不是异步的。
new Promise 的时候会立刻把 executor 函数执行(只不过咱们个别会在 executor 函数中解决一个异步操作)
// new Promise 的时候会立刻把 executor 函数执行let p1 = new Promise(() => { setTimeout((_) => { console.log(1); }, 1000); console.log(2);});console.log(3);// 2.3.1
2-2、Promise 状态
Promise {<pending>} __propt__:Promise [[PromiseStatus]]:"pending" [[PromiseValue]]:"undefined"// Promise 自身有一个 Value 值,用来记录胜利的后果(或者是失败的起因的) =>[[PromiseValue]]
Promise 自身有三个状态 => [[PromiseStatus]]
- pending 初始状态
- fulfilled 操作胜利实现
- rejected 操作失败
let p1 = new Promise((resolve, reject) => { setTimeout((_) => { // 个别会在异步操作完结后,执行resolve/reject函数,执行这两个函数中的一个,都能够批改Promise的[[PromiseStatus]]/[[PromiseValue]] // 一旦状态被扭转,在执行resolve、reject就没有用了 resolve("ok"); reject("no"); }, 1000);});
3、Promise 中的 then 和 catch
3-1、then(func1,func2) / then(func)
new Promise 的时候先执行 executor 函数,在这里开启了一个异步操作的工作(此时不等:把其放入到 EventQuque 工作队列中),继续执行
p1.then 基于 then 办法,存储起来两个函数(此时这两个函数还没有执行);当 executor 函数中的异步操作完结了,基于 resolve/reject 管制 Promise 状态,从而决定执行 then 存储的函数中的某一个
let p1 = new Promise((resolve, reject) => { setTimeout((_) => { let ran = Math.random(); console.log(ran); if (ran < 0.5) { reject("NO!"); return; } resolve("OK!"); }, 1000);});// then:设置胜利或者失败后处理的办法// Promise.prototype.then([resolvedFn],[rejectedFn])p1.then( // 胜利函数 (result) => { console.log(`胜利:` + result); }, // 失败函数 (reason) => { console.log(`失败:` + reason); });
resolve/reject 的执行,不管是否放到一个异步操作中,都须要期待 then 先执行完,把办法存储好,才会在更改状态后执行 then 中对应的办法 => 此处是一个异步操作(所以很多人说 Promise 是异步的),而且是微工作操作
let p1 = new Promise((resolve, reject) => { resolve(100);});p1.then( (result) => { console.log(`胜利:` + result); }, (reason) => { console.log(`失败:` + reason); });console.log(3);// 3// 胜利:100
创立一个状态为胜利/失败的 PROMISE 实例
这样的写法也能够被这种写法代替
Promise.resolve(100) | Promise.reject(0)
then 中也能够只写一个或者不写函数 ( .then(fn) | .then(null,fn) )
3-2、catch(func)
Promise.prototype.catch(fn)
===> .then(null,fn)
Promise.resolve(10) .then((result) => { console(a); //=>报错了 }) .catch((reason) => { console.log(`失败:${reason}`); });
3-3、then 链机制
then 办法完结都会返回一个新的 Promise 实例(then 链)
p1 这个 new Promise 进去的实例,胜利或者失败,取决于 executor 函数执行的时候,执行的是 resolve 还是 reject 决定的,再或者 executor 函数执行产生异样谬误,也是会把实例状态改为失败的
p2/p3 这种每一次执行 then 返回的新实例的状态,由 then 中存储的办法执行的后果来决定最初的状态(上一个 THEN 中某个办法执行的后果,决定下一个 then 中哪一个办法会被执行)
=> 不论是胜利的办法执行,还是失败的办法执行(then 中的两个办法),但凡执行抛出了异样,则都会把实例的状态改为失败
=> 办法中如果返回一个新的 Promise 实例,返回这个实例的后果是胜利还是失败,也决定了以后实例是胜利还是失败
=> 剩下的状况基本上都是让实例变为胜利的状态 (办法返回的后果是以后实例的 value 值:上一个 then 中办法返回的后果会传递到下一个 then 的办法中)
let p1 = new Promise((resolve, reject) => { resolve(100);});let p2 = p1.then( (result) => { console.log("胜利:" + result); return result + 100; }, (reason) => { console.log("失败:" + reason); return reason - 100; });let p3 = p2.then( (result) => { console.log("胜利:" + result); }, (reason) => { console.log("失败:" + reason); });
then 链式调用:
Promise.resolve(10) .then( (result) => { console.log(`胜利:${result}`); return Promise.reject(result * 10); }, (reason) => { console.log(`失败:${reason}`); } ) .then( (result) => { console.log(`胜利:${result}`); }, (reason) => { console.log(`失败:${reason}`); } );
遇到一个 then,要执行胜利或者失败的办法,如果此办法并没有在以后 then 中被定义,则顺延到下一个对应的函数
Promise.reject(10) .then((result) => { console.log(`胜利:${result}`); return result * 10; }) .then(null, (reason) => { console.log(`失败:${reason}`); });// 失败:10
4、Promise 中其它罕用办法
4.1、Promise.all
Promise.all(arr):返回的后果是一个 Promise 实例(all 实例),要求 arr 数组中的每一项都是一个新的 Promise 实例,Promise.all 是期待所有数组中的实例状态都为胜利才会让“all 实例”状态为胜利,Value 是一个汇合,存储着 arr 中每一个实例返回的后果;但凡 arr 中有一个实例状态为失败,“all 实例”的状态也是失败
let p1 = Promise.resolve(1);let p2 = new Promise((resolve) => { setTimeout((_) => { resolve(2); }, 1000);});let p3 = Promise.reject(3);Promise.all([p2, p1]) .then((result) => { // 返回的后果是依照 arr 中编写实例的程序组合在一起的 // [2,1] console.log(`胜利:${result}`); }) .catch((reason) => { console.log(`失败:${reason}`); });
4.2、Promise.race
Promise.race(arr):和 all 不同的中央,race 是赛跑,也就是 arr 中不论哪一个先解决完,解决完的后果作为“race 实例”的后果
4.3、Promise.reject (选)
4.4、Promise.resolve (选)
let p1 = Promise.resolve(100);let p2 = new Promise((resolve) => { setTimeout((_) => { resolve(200); }, 1000);});let p3 = Promise.reject(3);// 1 2 100
5、async/await
ES7 中提供了 Promise 操作的语法糖:async / await
async function handle() { let result = await ajax1(); result = await ajax2(result.map((item) => item.id)); result = await ajax3(); // 此处的result就是三次异步申请后获取的信息}handle();
async 是让一个一般函数返回的后果变为 status=resolved 并且 value=return 构造的 Promise 实例
async 最次要的作用是配合 await 应用的,因为一旦在函数中应用 await,那么以后的函数必须用 async 润饰
await 会期待以后 Promise 的返回后果,只有返回的状态是 resolved 状况,才会把返回后果赋值给 result
await 不是同步编程,是异步编程(微工作):当代码执行到此行(先把此行),构建一个异步的微工作(期待 Promise 返回后果,并且 Promise 上面的代码也都被列到工作队列中),
const p1 = () => new Promise();const p2 = () => new Promise();async function fn() { console.log(1); let result = await p2; console.log(result); let AA = await p1; console.log(AA);}fn();console.log(2);// 2// 1// p2 result// p1 AA
如果 Promise 是失败状态,则 await 不会接管其返回后果,await 上面的代码也不会在继续执行( await 只能解决 Promise 为胜利状态的时候)
const p3 = Promise.reject(10);async function fn() { let reason = await p3; console.log(reason);}fn();//
编辑工夫:2020-08-18 21:15