MDN Promise 文档javascript
Promise 及其做用java
Promise 的 executor 函数和状态ajax
Promise 状态编程
Promise 中的 then 和 catch设计模式
Promise 中其它经常使用方法数组
Promise 的诞生就是为了解决异步请求中的回调地狱问题:它是一种设计模式,ES6 中提供了一个 JS 内置类 Promise,来实现这种设计模式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) => {});
回调地狱:上一个回调函数中继续作事情,并且继续回调(在真实项目的 AJAX 请求中常常出现回调地狱)=> 异步请求、不方便代码的维护dom
new Promise([executor]) ,[executor]执行函数是必须传递的异步
Promise 是用来管理异步编程的,它自己不是异步的。async
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
Promise {<pending>} __propt__:Promise [[PromiseStatus]]:"pending" [[PromiseValue]]:"undefined" // Promise 自己有一个 Value 值,用来记录成功的结果(或者是失败的缘由的) =>[[PromiseValue]]
Promise 自己有三个状态 => [[PromiseStatus]]
let p1 = new Promise((resolve, reject) => { setTimeout((_) => { // 通常会在异步操做结束后,执行resolve/reject函数,执行这两个函数中的一个,均可以修改Promise的[[PromiseStatus]]/[[PromiseValue]] // 一旦状态被改变,在执行resolve、reject就没有用了 resolve("ok"); reject("no"); }, 1000); });
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) )
Promise.prototype.catch(fn)
===> .then(null,fn)
Promise.resolve(10) .then((result) => { console(a); //=>报错了 }) .catch((reason) => { console.log(`失败:${reason}`); });
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
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}`); });
Promise.race(arr):和 all 不一样的地方,race 是赛跑,也就是 arr 中无论哪个先处理完,处理完的结果做为“race 实例”的结果
let p1 = Promise.resolve(100); let p2 = new Promise((resolve) => { setTimeout((_) => { resolve(200); }, 1000); }); let p3 = Promise.reject(3); // 1 2 100
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