JavaScript之Promise实现
ES2015提出了Promise
,同时基于Promise
的异步开发将开发者中回调地狱中解救出来。但在没有原生支持的环境下,需要借助Promise/A+
之类的库来实现Promise
,今天就来尝试自行实现Promise。
1 基本实现
首先来完成一个Promise
类的基本框架:
function Promise(fn) {var resolveCallback = nullvar rejectCallback = nullthis.then = function(onResolved, onRejected) {resolveCallback = onResolvedrejectCallback = onRejected}this.resolve = function(value) {this.resolveCallback(value)}this.reject = function(reason) {this.rejectCallback(reason)}fn(this.resolve, this.reject)
}
以上便是Promise
的基本实现。
2 状态管理
上述的代码存在一个问题,resolve方法会调用多次,所以接下来我们需要接入状态管理。
Promise
内部存在3个状态:
- pending
- resolved
- rejected
接下来在现有代码之上,加入状态管理:
function MyPromise(fn) {let state = 'pending'var resolveCallback = nullvar rejectCallback = nullvar childResolvevar childRejectthis.then = function(onResolved, onRejected) {resolveCallback = onResolvedrejectCallback = onRejected}this.resolve = function(value) {if(state === 'pending') {this.resolveCallback(value)state = 'resolved' } }this.reject = function(reason) {if(state === 'pending') {this.rejectCallback(reason)state = 'rejected'} }fn(this.resolve, this.reject)
}
3 链式调用
上述Promise
实现可以完成正常的异步调用,但是却无法实现链式回调,原因在于其then
方法没有返回一个新的Promise
对象,所以接下来还需要改造then
方法,实现链式调用:
this.then = function(onResolved, onRejected) {if(state === 'pending') {resolveCallback = onResolvedrejectCallback = onRejected}return new MyPromise((resolve, reject) => {......})}
光返回一个promise
对象还没用,接下来我们来写个demo测试下:
var demo = new MyPromise((resolve, reject) => {setTimeout(() => {resolve('my first promise')}, 1000)})demo.then((msg) => {console.log(msg)return 'my second promise'}).then((msg) => {console.log(msg)})
其输出为:
my first promise
事实上,第二个promise对象的resolve
reject
方法从未被调用过,因而其onResolved
onRejected
的回调ye就无从调用。所以还必须指定时机调用字promise
对象的resolve
和reject
。
所以首先需要在创建新promise
对象时,记录其resolve
和reject
方法:
function MyPromise() {......var childResolvevar childRejectthis.then = function(onResolved, onRejected) {if(state === 'pending') {resolveCallback = onResolvedrejectCallback = onRejected}return new MyPromise((resolve, reject) => {childResolve = resolvechildReject = reject})}
}
接下来还需在resolve
和 reject
方法中调用子对象的resolve
和reject
方法,整个Promise
完整代码如下:
function MyPromise(fn) {let state = 'pending'var resolveCallback = nullvar rejectCallback = nullvar childResolve = nullvar childReject = nullthis.then = function(onResolved, onRejected) {if(state === 'pending') {resolveCallback = onResolvedrejectCallback = onRejected}return new MyPromise((resolve, reject) => {childResolve = resolvechildReject = reject})}this.resolve = function(value) {if(state === 'pending') {if(resolveCallback) {var ret = resolveCallback(value)childResolve(ret)state = 'resolved' }} }this.reject = function(reason) {if(state === 'pending') {if(rejectCallback) {var ret = rejectCallback(reason)childReject(ret)state = 'rejected'}} }fn(this.resolve, this.reject)}
JavaScript之Promise实现相关推荐
- JavaScript 的 Promise 和 C# 的 waitone 一样吗?请大家讨论i两句。
JavaScript 的 Promise 和 C# 的 waitone 一样吗?请大家讨论i两句.
- JavaScript之Promise
看完下面文章,你将了解到: 1.什么是Promise? 2.Promise怎样使用以及使用的场景,解决了什么问题 3.ES7较ES6又增加了哪些支撑Promise的语法糖 复制代码 一.Promise ...
- 实现 JavaScript 异步方法 Promise.all
本次的任务 假如..... JavaScript v8 引擎发生了重大故障,Promise.all 方法变成了 undefined ,为了拯救 JavaScript 世界,需要开发一个模块来解决此问题 ...
- 你真的了解JavaScript的Promise吗?
什么是Promise Promise代理了一个可能要在未来才能到达的值[[PromiseValue]].Promise的一个最重要的特点是,你可以通过then来指定当[[PromiseValue]]到 ...
- javascript的promise
'use strict'; // ajax函数将返回Promise对象: function ajax(method, url, data) {var request = new XMLHttpRequ ...
- Javascript ES6 Promise同步读取文件(使用async、await)
const fs=require('fs'); const path=require('path');const dirname='D:\\HBuilderX\\Workspace\\NodeJS\\ ...
- Javascript ES6 Promise异步链式读取文件解决回调地狱
const fs=require('fs'); const path=require('path');const dirname='D:\\HBuilderX\\Workspace\\NodeJS\\ ...
- JavaScript:Promise进阶知识
Promise Promise就是ES6新增的一个用于解决异步编程的方案.以前,我们在处理异步的时候,都是在回调函数内做处理的.比如Ajax请求,是在success属性里面做异步处理的,那么如果在一个 ...
- 学习笔记 JavaScript ES6 Promise的静态方法
学习内容: Promise.resolve() Promise.reject() Promise.all() Promise.race() Promise.resolve(),表示成功的状态 Prom ...
最新文章
- python中内置的四种数值类型为_浅谈python语言四种数值类型
- 步进电机正反转实验_电工基础:帮你学会电机正反转双重互锁控制
- app服务器一种什么样的服务器
- c51语言定义全局变量,全局变量的定义和使用
- 13个AJAX验证框架
- 第 3 章 第 2 题 求级数问题 递归法实现
- Netty权威指南之伪异步I/O编程
- 关于winodows下编程c++遇到的引用文件路径问题
- HSRPSTPACL
- 国科大高级人工智能5-RNN/LSTM/GRU/集束搜索/attention
- kax格式怎么导入不了pr_pr如何导入.mogrt文件 pr模板导入教程
- php mysql登陆页面完整代码_求助:PHP实现登陆注册的代码是什么啊(主要是数据库那块)?...
- 阿里云服务器如何修改密码
- Python基础—文件操作
- Shiro保姆级教程
- IPhone手机无法连接蓝牙
- 调研主板,树莓派 VS RK3288板子,还是 RK的主板香,但是只支持 anrdoid 7系统,估计也有刷机成 armbian或者
- Allegro PCB Design GXL (legacy) - 铺网格铜
- matlab 求曲面体积,matlab求两曲面之间的体积
- 网络七层协议:OSI七层协议大白话解读