Promise基本概念
Promise含义
Promise是异步编程的一种解决方案。简单说就是一个容器,里面保存着某个未来才会结束的事件的结果。从语法上讲,Promise是一个对象,从它可以获取异步操作的消息。
Promise的原理
Promise提供一个包裹异步操作处理的容器,容器通过三个不同状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)输出处理程序的结果,通过then或catch方法接收异步处理操作的结果并对结果做相应处理。then方法的链式调用避免了传统函数回调嵌套,增强了代码的可读性。
Promise的特点
- Promise对象的状态不受外界影响。Promise有三种状态:pending(运行中)、fulfilled(已成功)、rejected(已失败)。只有异步操作的结果可以决定当前是哪种状态,任何其他操作都无法改变这个状态
- 一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变只有两种可能:从pending到fulfilled和从pending到rejected。只要这两种情况发生,状态就不会再变,称为定型(resolved)
Promise的缺点
- 无法取消,一旦新建它就会立即执行,中途无法取消
- 如果不设置回调函数,Promise内部抛出的错误无法反应到外部
- 当处于pending状态时,无法的得知目前进行到哪一个阶段
Promise的简单实现
-
定义MyPromise类。定义MyPromise中自身属性及绑定
class MyPromise { constructor (fn) { const that = this that._value = 0 } } 复制代码
-
在MyPromise实例化时,需要传入一个函数作为参数,函数有需要resolve和reject函数作为参数。实现方法如下:
function tryCallTwo (fn, a, b) { try { fn (a, b) } catch (e) { return e } } 复制代码
将此方法在MyPromise类的内部调用,完成传入fn函数的绑定。
class MyPromise { constructor (fn) { const that = this that._value = 0 tryCallTwo (fn, function (value) { console.log(value) // 2 }, function (err) { console.log(err) }) } } new MyPromise(function (resolve, reject) { resolve(2) }) 复制代码
通过tryCallTwo方法将实例化时传入的函数的resolve或reject转化为处理函数;通过以上打印可知tryCallTwo方法的第二个参数就是实例化时传入的resolve的处理函数。在MyPromise类中tryCallTwo方法中的第二个参数内部,调用resolve方法,作为处理函数。MyPromise类修改如下:
class MyPromise { constructor (fn) { const that = this that._value = 0 tryCallTwo (fn, function (value) { console.log(value) // 2 resolve(that, value) }, function (err) { console.log(err) }) } } 复制代码
-
定义resolve方法,此方法需要传入当前的实例作为第一个参数,实例化时resolve(2)传入的值作为第二个参数。在resolve方法中相当于修改MyPromise类中_value的值
function resolve (self, newValue) { self._value = newValue } 复制代码
-
到此为止MyPromise的输出已经解决,接下来定义接收处理方法then。由于then是实例方法,所以要定义在MyPromise类的内部
class MyPromise { constructor (fn) {...} then (onFulfilled) { // 判断then传入的参数是否是function let cb = typeof onFulfilled === 'function' ? onFulfilled : null // 如果cb存在为其添加处理过程 cb && tryCallOne(cb, that._value) } } 复制代码
-
定义tryCallOne方法
tryCallOne (fn, a) { try { return fn (a) } catch (e) { return e } } 复制代码
-
通过实例调用then方法
new MyPromise(function (resolve, reject) { resolve(3) }).then(res => { console.log(res) // 3 }) 复制代码
完整代码
// 实现MyPromise构造函数两个函数参数的绑定
function tryCallTow (fn, a, b) {
try {
fn(a, b)
} catch (ex) {
return ex
}
}
// 实现then方法中函数参数传入
function tryCallOne (fn, a) {
try {
return fn(a)
} catch (ex) {
return ex
}
}
// resolve方法
function resolve (self, newValue) {
self._value = newValue
}
// noop方法:在resolve传入简单数据类型值时作为参数传给
class MyPromise {
constructor(fn) {
const that = this
this._value = 0
tryCallTow(fn, function (value) {
resolve(that, value)
}, function (err) {
console.log(err)
})
}
then (onFulfilled) {
let cb = typeof onFulfilled === 'function' ? onFulfilled : null
cb && tryCallOne(cb, this._value)
}
}
复制代码
完整的运行流程
参考文献
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END