promise与 fetch、async/await

promise与 fetch、async/await 目录promise应用webpack loaderpromise手写Promise.prototype(实例)方法均返回promisethen回调函数resolveFn的形参resolve的参数catch回调函数rejectFn的形参reject的参数异常穿透错误的传递就近的 onRejected /catchfinally回调函数返回上一次的Promise对象值/promise包装的errorPromise并发方法返回数组allSettled() 返回 任务 结束结果 不会走catch适用于 结果不依赖all返回 所有成功/首个失败结果依赖map获取每个结果promise.reslove(catch)返回 第一个race竞速第一个完成其他的方法仍在执行any第一个成功都失败则catch包含所有失败原因的 AggregateError 错误对象观察者模式创建Promise实例await 值Promise.resolve(值)Promise.resolve(值)如果该值本身就是一个 promise实例将直接被返回Promise.reject(值)constructor的函数参数起始函数同步立即执行起始函数的函数参数均可选resolve 起始函数成功时调用、reject失败时调用状态都没有的话状态为pending[待定]初始状态错误无法捕获异步回调中promise已结束解决executor 中的异步错误resolve/reject ,便于后续链式调用try…catch promise 内部的错误不会冒泡A.then、catch捕获B.async/await中断promisereturn pending 的 promisenew Promise(() {})fetch es6 api基于promise简单易用回调函数参数为函数且满足条件才执行该参数函数隐式return 原promise对象/ 显式return 非promise会包装成promisethen/catch/finally/asyncasync/await函数async关键字函数await 操作符promise对象promise对象变成reject状态时整个async函数会中断处理异常 try-catch 块promise应用webpack loaderpromise手写Promise.prototype(实例)方法均返回promisethen回调函数resolveFn的形参resolve的参数catch回调函数rejectFn的形参reject的参数promise.then(f1).catch(f2); //f1 和 f2处于同一层级二者只会执行其一下面没有链所以 error 不会被处理。 promise.then(f1, f2);异常穿透错误的传递就近的onRejected/catch一遇到异常抛出浏览器就会顺着 Promise 链寻找下一个就近的onRejected失败回调函数或者由.catch()指定的回调函数。new Promise((resolve, reject) { reject(失败了) }) .then( (data) { console.log(onResolved1, data); }, (error) { console.log(onRejected2, error); } ) .catch( (error) { console.log(catch, error) } )失败了就会被离它最近的 then 中的onRejected函数所处理而不会被 catch 所捕获。finally回调函数返回上一次的Promise对象值/promise包装的errorPromise并发方法返回数组allSettled()返回 任务 结束结果 不会走catch适用于 结果不依赖all返回 所有成功/首个失败结果依赖const promise1 Promise.resolve(3); const promise2 42; const promise3 new Promise((resolve, reject) { setTimeout(resolve, 100, foo);//setTimeout(function[, delay, arg1, arg2, ...]); }); Promise.all([promise1, promise2, promise3]).then((values) { console.log(values); }); // Expected output: Array [3, 42, foo]map获取每个结果promise.reslove(catch)catch方法返回的promise实例会被promise.reslove()包裹这样传进promise.all的数据都是resolved状态的。let p1 Promise.resolve(1) let p2 Promise.resolve(2) let p3 Promise.resolve(3) let p4 Promise.resolve(4) let p5 Promise.reject(error) let arr [p1,p2,p3,p4,p5]; let all Promise.all(arr.map((promise)promise.catch((e){console.log(错误信息e)}))) all.then(res{console.log(res)}).catch(errconsole.log(err));返回 第一个race竞速第一个完成其他的方法仍在执行any第一个成功都失败则catch包含所有失败原因的AggregateError错误对象观察者模式const p1 new Promise((resolve, reject) { setTimeout(() { resolve(result) }, 1000); }) p1.then(res console.log(res), err console.log(err))分析Promise的调用流程Promise的构造方法接收一个executor()在new Promise()时就立刻执行这个executor回调executor()内部的异步任务被放入宏/微任务队列等待执行then()被执行收集成功/失败回调放入成功/失败队列executor()的异步任务被执行触发resolve/reject从成功/失败队列中取出回调依次执行观察者模式收集依赖 - 触发通知 - 取出依赖执行在Promise里执行顺序是then收集依赖 - 异步触发resolve - resolve执行依赖。class MyPromise { // 构造方法接收一个回调 constructor(executor) { this._resolveQueue [] // then收集的执行成功的回调队列 this._rejectQueue [] // then收集的执行失败的回调队列 /*由于resolve/reject是在executor内部被调用, 因此需要使用箭头函数固定this指向, 否则找不到this._resolveQueue*/ let _resolve (val) { // 从成功队列里取出回调依次执行 while(this._resolveQueue.length) { const callback this._resolveQueue.shift() callback(val) } } // 实现同resolve let _reject (val) { while(this._rejectQueue.length) { const callback this._rejectQueue.shift() callback(val) } } // new Promise()时立即执行executor,并传入resolve和reject executor(_resolve, _reject) } // then方法,接收一个成功的回调和一个失败的回调并push进对应队列 then(resolveFn, rejectFn) { this._resolveQueue.push(resolveFn) this._rejectQueue.push(rejectFn) } }创建Promise实例await 值Promise.resolve(值)Promise.resolve(值)如果该值本身就是一个 promise实例将直接被返回Promise.reject(值)constructor的函数参数起始函数同步立即执行起始函数的函数参数均可选resolve起始函数成功时调用、reject失败时调用状态都没有的话状态为pending[待定]初始状态//​​什么都不输出​​​​​ new Promise((){}).then((){ console.log(then) }).finally((){ console.log(finally) })【建议星星】要就来45道Promise面试题一次爽到底(1.1w字用心整理) - 掘金错误无法捕获异步回调中promise已结束在延时等待 1s 后抛出错误这一操作才会执行但此时外面的 Promise早就执行结束。因此promise 无法处理它程序会在此崩掉。new Promise((resolve, reject) { setTimeout(() { throw new Error(Whoops!); }, 1000); }) .catch(error { console.log(catch error:, error); }); //无任何输出解决executor 中的异步错误resolve/reject,便于后续链式调用new Promise((resolve, reject) { setTimeout(() { try { resolve() } catch(error) { reject(error) } }, 1000); })try…catch promise 内部的错误不会冒泡function fn1() { try { new Promise((resolve, reject) { throw new Error(promise1 error) }) } catch (error) { console.log(e.message); } } function fn2() { try { Promise.reject(promise2 error); } catch (error) { console.log(error); } }A.then、catch捕获B.async/await// 模拟请求 function http(params) { return new Promise((resolve, reject) { setTimeout(() { if (params 0) reject(error) resolve(success) }, 1000); }) } // 业务调用 async function query(params) { try { const data await http(params) console.log(data:, data); } catch (error) { console.log(error:, error); } } query(0)中断promisereturn pending 的 promisenew Promise(() {}).catch((err) { console.log(onRejected, err); // 中断promise链: return new Promise(() {}) })fetch es6 api基于promise简单易用window.fetch(url, { method: get}) //fetch() 返回响应的promise // 第一个then 设置请求的格式 .then(res return res.json()) // 第一层then返回的是:响应的报文对象 .then((data) { //第二层:如果想要使用第一层的数据,必须把数据序列化 res.json() 返回的对象是一个 Promise对象再进行then() !-- data为真正数据 -- }).catch(e console.log(Oops, error, e))回调函数参数为函数且满足条件才执行该参数函数隐式return 原promise对象/ 显式return 非promise会包装成promisethen/catch/finally/asyncasync/await函数Promise.resolve(a) .then(b { // do something }) .then(c { // do something }) //等价于 async () { const a await Promise.resolve(a); const b await Promise.resolve(b); const c await Promise.resolve(c); }async关键字函数await操作符promise对象promise对象变成reject状态时整个async函数会中断处理异常 try-catch 块async function asyncFunc() { try { await new Promise(function (resolve, reject) { throw Some error; // 或者 reject(Some error) }); } catch (err) { console.log(err); // 会输出 Some error } } asyncFunc();