Promise手写|博客系列
# Js中error处理
- Error 所有错误的父类型
- ReferenceError 引用变量不存在
- TypeError 数据类型不存在
- RangeError 数据值不在允许范围内
- SyntaxError 语法错误
错误处理
- 捕获对象 try catch
- 抛出错误 throw error
错误对象
- message属性 错误相关信息
- stack属性 函数调用栈记录信息
异步编程
- callback(回调函数)
- generator + co库
- Promise
- async + await
# Promise理解和使用
- Promise是什么
- 为什么使用Promise
- 如何使用Promise
# Promise是什么
- 抽象表达:Promise是JS中进行异步编程的新的解决方案
- 具体表达:语法上,Promise是一个构造函数。
- 功能上说:Promise对象是用来封装一个异步操作并可以获取其结果
# Promise的状态改变
- pending变为resolved
- pending变为rejected
- 说明:只有这两种,且一个Promise对象只能改变一次,无论变为成功还是失败,都会有一个结果数据。成功的结果数据一般称为value,失败的结果一般称为reson
# 为什么要用Promise 优点是什么
-
- 指定回调函数方式更加灵活,灵活的方面指的就是时间上面的问题。旧的方式必须启动异步任务前就指定,Promise可以在启动异步任务之后,或者说比如请求一个数据,三秒内可以获取结果,可是我们可以在5秒后在指定这个回调函数,去完成对应的任务。
- 支持链式调用,可以解决回调地狱问题。
- 回调地狱:回调函数嵌套调用,外部回调函数异步执行的结果是内部嵌套函数执行的条件。
- 回调地狱缺点:不方便阅读,不便于异常处理。
- 比如多个串联异步任务,第二个异步任务条件是第一个异步任务成功的结果。
终极解决方案:async/await
# 如何使用Promise
# 对应的API:
# Promise构造函数: Promise(excutor){}
- excutor函数:同步执行 (resolve,reject) => {}
- resolve函数:内部定义成功时我们调用的函数 value =>{}
- reject函数:内部定义失败时我们调用的函数 reson =>{}
- 说明:excutor会在Promise内部立即同步回调,异步操作在执行器中执行
# Promise.prototype.then()方法:(onResolved,onRejected) => {}
- onResolved函数:成功的回调函数(value) => {}
- onRejected函数: 失败的回调函数(reson) =>{}
- 说明:它最多需要有两个参数:Promise 的成功和失败情况的回调函数。最后放回一个Promise对象
# Promise.prototype.catch(onRejected)方法:
-
catch() 方法返回一个Promise,并且处理拒绝的情况。
-
catch() 方法返回一个Promise,并且处理拒绝的情况。它的行为与调用
Promise.prototype.then(undefined, onRejected)相同。 -
当Promise 被rejected时,被调用的一个
Function。 该函数拥有一个参数:reasonrejection 的原因。
# Promise.resolve(value)方法:
-
静态方法
Promise.resolve返回一个解析过的Promise对象。 -
value:将被
Promise对象解析的参数,也可以是一个Promise对象,或者是一个thenable。 -
返回值:返回一个带着给定值解析过的
Promise对象,如果参数本身就是一个Promise对象,则直接返回这个Promise对象。
# Promise.reject(reason)方法:
-
**Promise.reject()**方法返回一个带有拒绝原因的Promise对象。 -
reason:表示
Promise被拒绝的原因。 -
返回值:一个给定原因了的被拒绝的Promise对象
-
描述:静态函数
Promise.reject返回一个被拒绝的Promise对象。通过使用Error的实例获取错误原因reason对调试和选择性错误捕捉很有帮助。
Promise.all(iterable)方法:
-
返回一个
Promise实例,此实例在iterable参数内所有的promise都“完成(resolved)”或参数中不包含promise时回调完成(resolve);如果参数中promise有一个失败(rejected),此实例回调失败(reject),失败的原因是第一个失败promise的结果。 -
它通常在启动多个异步任务并发运行并为其结果创建承诺之后使用,以便人们可以等待所有任务完成。
-
放回值:
# Promise几个关键问题
- 如何改变Promise的状态
- resolve(value):如果当前是pending就会变为resolved
- reject(reason):如果当前是pending就会变为rejected
- 抛出异常:如果当前是pending就会变为rejected
- 一个Promise指定多个成功/失败回调函数,都会调用吗?
- 当Promise改变为对应状态时都会调用
- 改变Promise状态和指定回调函数谁先谁后?
- 都有可能,正常情况下是先指定回调再改变状态,但也有可能先改变状态再指定回调函数。
- 如何先改变状态再指定回调呢?
- 在执行器中直接调用resolve() / reject()
- 延迟更长时间去调用then()
- 什么时候才能得到数据
- 如果先指定回调,那当状态改变时,回调函数调用,得到数据
- 如果是先改变状态,那当指定回调时,回调函数就会调用,得到数据。
- Promise.then() 返回的新Promise的结果状态由什么决定
- 简单表达:由then()指定的回调函数执行的结果决定
- 详细表达:
- 如果抛出异常,新Promise变为rejected,reason为抛出的异常,抛出err,则reason就是err,抛出数值,也就是数值
- 如果返回的时非Promise任意值,新Promise状态就是resolve,value就是返回值
- 如果返回的时另一个新Promise,此Promise的结果就是新Promise结果
- Promise如何串连多个操作任务
- Promise的then()返回一个新Promise,可以看成then的链式调用
- 通过then链式调用串连多个同步/异步任务
- 值得注意的是:在then()中实现异步任务的话,需要new Promise()将异步代码包裹起来
- Promise异常穿透
- 当使用Promise的then链式调用时,可以在最后指定失败的回调。
- 前面任何操作出现了异常,会传到最后失败的回调中处理,有时候,then( value => {})不指定失败的回调函数,是因为默认给你加上then(value =>{}, reason => {throw reason})
- 中断Promise链
- 当使用Promise的then链式调用时,在中间中断,不在调用后面的回调函数
- 办法:在回调函数中return new Promise(() => {})
# 自定义Promise(手写)
# 整体结构
/**
自定义Promise函数模块:IIFE
*/
(function(window){
/**
* Promise构造函数
* executor 执行器函数
* @param {*} executor
*/
function Promise(executor) {
}
/**
* Promise原型对象的then()
* 指定成功和失败的回调函数
* 返回一个新的promise对象
*/
Promise.prototype.then = function (onSolved, onRejected){
}
/**
* Promise原型对象上的catch()
* 指定失败的回调函数
* 返回一个新的promise对象
*/
Promise.prototype.catch = function (onRejected) {
}
/**
* Promise函数对象上resolve方法
* 返回一个成功的Promise,值为value
*/
Promise.resolve = function(value) {
}
/**
* Promise函数对象上reject方法
* 返回一个失败的Promise,值为reason
*/
Promise.reject = function(reason) {
}
/**
* Promise函数对象上all方法
* 返回一个promise,只有当所有的promise都成功才为成功状态,否则为失败
*/
Promise.all = function(promises) {
}
/**
* Promise函数对象上race方法
* 返回一个promise对象,其结果取决于第一个完成的Promise
*/
Promise.race = function(promises) {
}
window.Promise = Promise;
})(window)
