ES6之promise原理
栏目: JavaScript · 发布时间: 5年前
内容简介:Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数更强大,避免了层层回调。它由社区最早提出和实现,ES6将其写进了语言标准,统一了用法,现在原生提供Promise对象!Promise 是一个状态工具,他有三个状态:pending, fulfilled, reject,因此我们先定义三个状态。Promise 在执行完异步操作后,会转变状态,所以代码变为这样。
Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数更强大,避免了层层回调。它由社区最早提出和实现,ES6将其写进了语言标准,统一了用法,现在原生提供Promise对象!
Promise使用:
// ... some code const promise = new Promise(function(resolve, reject) { if (/* 异步操作成功 */){ resolve(value); } else { reject(error); } }); 复制代码
- 我们可以看到,promise需要使用new操作符来生成实例,因此Promise是一个构造函数。
- 这个promise初始化的时候需要传入一个函数做为参数,并且这个函数的两个参数分别为:resolve和reject。
- resolve和reject是两个函数, 由 JavaScript 引擎提供 ,不用自己部署。
- resolve函数的作用:将Promise对象状态从pending 变为 fulfilled 。
- reject 函数的作用:将Promise对象状态从pending 变为 reject 。
现在让我们看一下promise的原理
Promise 是一个状态工具,他有三个状态:pending, fulfilled, reject,因此我们先定义三个状态。
var PENDING = 0; var FULFILLED = 1; var REJECTED = 2; function Promise() { // store state which can be PENDING, FULFILLED or REJECTED var state = PENDING; // store value or error once FULFILLED or REJECTED var value = null; // store sucess & failure handlers attached by calling .then or .done var handlers = []; } 复制代码
Promise 在执行完异步操作后,会转变状态,所以代码变为这样。
var PENDING = 0; var FULFILLED = 1; var REJECTED = 2; function Promise() { // store state which can be PENDING, FULFILLED or REJECTED var state = PENDING; // store value once FULFILLED or REJECTED var value = null; // store sucess & failure handlers var handlers = []; function fulfill(result) { state = FULFILLED; // 状态改变了 value = result; } function reject(error) { state = REJECTED; // 状态改变了 value = error; } } 复制代码
上面fulfill是一个比较low level的转变状态方法,但是有一个higher-level的转变状态方法: resolve
var PENDING = 0; var FULFILLED = 1; var REJECTED = 2; function Promise() { // store state which can be PENDING, FULFILLED or REJECTED var state = PENDING; // store value once FULFILLED or REJECTED var value = null; // store sucess & failure handlers var handlers = []; function fulfill(result) { state = FULFILLED; value = result; } function reject(error) { state = REJECTED; value = error; } function resolve(result) { try { var then = getThen(result); if (then) { doResolve(then.bind(result), resolve, reject) return } fulfill(result); } catch (e) { reject(e); } } } 复制代码
可以看到resolve先调用了方法getThen(),这个方法是判断result是否是promise,如果是的话,调用这个promise的then方法(使用doResolve()方法),如果不是的话,调用fulfill()方法。
/** * Check if a value is a Promise and, if it is, * return the `then` method of that promise. * * @param {Promise|Any} value * @return {Function|Null} */ function getThen(value) { var t = typeof value; if (value && (t === 'object' || t === 'function')) { var then = value.then; if (typeof then === 'function') { return then; } } return null; } /** * Take a potentially misbehaving resolver function and make sure * onFulfilled and onRejected are only called once. * * Makes no guarantees about asynchrony. * * @param {Function} fn A resolver function that may not be trusted * @param {Function} onFulfilled * @param {Function} onRejected */ function doResolve(fn, onFulfilled, onRejected) { var done = false; try { fn(function (value) { if (done) return done = true onFulfilled(value) }, function (reason) { if (done) return done = true onRejected(reason) }) } catch (ex) { if (done) return done = true onRejected(ex) } } 复制代码
这里可以看到,什么情况会reject:catch到的错误会reject, 到现在为止,我们完成了内部状态机,可是介绍resolving这个promise的方法:
var PENDING = 0; var FULFILLED = 1; var REJECTED = 2; function Promise(fn) { // store state which can be PENDING, FULFILLED or REJECTED var state = PENDING; // store value once FULFILLED or REJECTED var value = null; // store sucess & failure handlers var handlers = []; function fulfill(result) { state = FULFILLED; value = result; } function reject(error) { state = REJECTED; value = error; } function resolve(result) { try { var then = getThen(result); if (then) { doResolve(then.bind(result), resolve, reject) return } fulfill(result); } catch (e) { reject(e); } } doResolve(fn, resolve, reject); } 复制代码
只添加了最后一句代码: 我们re-use了doResolve()方法!
现在我们已经完成了状态机,可是我们仍然无法监听变化,我们的最终目标是实现.then(), 但是.done()这个更简单,因此,让我们先实现.done()吧! 所以我们的目标是实现promise.done(onFulfilled, onRejected), 他有以下特点
- 只调用 onFulfilled or onRejected 中的一个
- 只调用一次
var PENDING = 0; var FULFILLED = 1; var REJECTED = 2; function Promise(fn) { // store state which can be PENDING, FULFILLED or REJECTED var state = PENDING; // store value once FULFILLED or REJECTED var value = null; // store sucess & failure handlers var handlers = []; function fulfill(result) { state = FULFILLED; value = result; handlers.forEach(handle); handlers = null; } function reject(error) { state = REJECTED; value = error; handlers.forEach(handle); handlers = null; } function resolve(result) { try { var then = getThen(result); if (then) { doResolve(then.bind(result), resolve, reject) return } fulfill(result); } catch (e) { reject(e); } } function handle(handler) { if (state === PENDING) { handlers.push(handler); } else { if (state === FULFILLED && typeof handler.onFulfilled === 'function') { handler.onFulfilled(value); } if (state === REJECTED && typeof handler.onRejected === 'function') { handler.onRejected(value); } } } this.done = function (onFulfilled, onRejected) { // ensure we are always asynchronous setTimeout(function () { handle({ onFulfilled: onFulfilled, onRejected: onRejected }); }, 0); } doResolve(fn, resolve, reject); } 复制代码
this.done方法做的事情:执行了handle方法,并传入参数,其中参数就是第一个是成功时候回调函数,第二个是reject时候的回调函数。
现在让我们实现.then吧~
this.then = function (onFulfilled, onRejected) { var self = this; return new Promise(function (resolve, reject) { return self.done(function (result) { if (typeof onFulfilled === 'function') { try { return resolve(onFulfilled(result)); } catch (ex) { return reject(ex); } } else { return resolve(result); } }, function (error) { if (typeof onRejected === 'function') { try { return resolve(onRejected(error)); } catch (ex) { return reject(ex); } } else { return reject(error); } }); }); } 复制代码
- .then 和.done一样,接受两个参数,第一个是成功时候回调函数onFulfilled,第二个是失败时候回调函数onRejected。
- .then 能实现链式调用,就是因为其返回了一个promise。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- java反射原理, 注解原理
- Webpack 原理(二):加载原理
- Docker原理之 - CGroup实现原理
- 【Vue原理】响应式原理 - 白话版
- Docker实现原理之 - OverlayFS实现原理
- UAV MOF工作原理之Agent注入机制原理
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Beginning Java Objects中文版从概念到代码
巴克 / 万波 / 人民邮电出版社 / 2007-1 / 78.00元
《Beginning Java Objects中文版从概念到代码(第2版)》是关于软件对象和Java的,但并不是纯粹地介绍Java语言,而是强调如何从对象模型转换到功能完整的Java应用程序。书中讲述了对象基础、对象建模和模型的实现。《Beginning Java Objects中文版从概念到代码(第2版)》除了用学生注册系统(SRS)示例贯穿全书之外,还在附录中给出三个附加的案例,这些案例是每章......一起来看看 《Beginning Java Objects中文版从概念到代码》 这本书的介绍吧!
HTML 编码/解码
HTML 编码/解码
HSV CMYK 转换工具
HSV CMYK互换工具