之前学React的时候同步方案直接用的async然后babel转换成ES5
最近开始制作小程序(没有同步操作),顺便就研究了一下Promise的具体实现(我一直以为这不是通过代码能实现的)
我个人比较笨,研究了大概得有一天半才明白了大概原理并写出了一个属于我自己的Promise(长的都差不多)
话不多说,直接上代码 PS:如果你连如何使用都不会,建议你去看一下如何使用---阮一峰 ES6 Promise
function promise(fn) {
if (typeof this !== "object") throw new TypeError('必须使用new创建Promise')
if (typeof fn !== "function") throw new TypeError('参数不是一个function')
// 状态机
var state = null
// 结果集
var resource = null
// 回调函数列
// 有一件有趣的事(魔法:未知才有趣)
// 当你使用链式操作的时候
// deferreds始终只有一个回调函数
// 但是如果你pro.then(...);pro.then(...);这种操作的话就会有多个
var deferreds = []
// 当前Promise
var self = this
/**
* 然后
*
* then函数理解为:做完当前事后要做的事
* return new Promise:我做完当前的事了,后面的事我交给另一个Promise了
* 这里的handle函数 我在handle上会写注释
*/
this.then = function (onFulfilled, onRejected) {
return new self.constructor(function (resolve, reject) {
handle(new Handler(onFulfilled, onRejected, resolve, reject))
})
}
/**
* 处理
*
* (onFulfilled, onRejected) 前面的Promise做完事了要如何处理('如何处理'这事委托给了当前的Promise)
* (resolve, reject) 当前Promise宣告事情做完的结果
*
* state === null 表示前面Promise还没收到事情完成的通知 这时候你可以告诉他接下来要做的事(也就是添加回调)
* state !== null
* state === true 前面的Promise已经把他自己的事做好了 根据前面Promise的执行结果(state)当前Promise要做自己的事(执行onFulfilled或onRejected) 当自己的事做完以后宣告事情已经处理完(成功:resolve, 失败:reject)
* state === false 执行onRejected || reject ps:哪里发生了一些错误(可能是外部传入的回调错误)
*/
function handle(deferred) {
if (state === null) {
deferreds.push(deferred)
return
}
var cb = state ? deferred.onFulfilled : deferred.onRejected
if (cb === null) {
(state ? deferred.resolve : deferred.reject)(resource)
return
}
var ret
try {
ret = cb(resource) || resource
} catch (e) {
deferred.reject(e)
return
}
deferred.resolve(ret)
}
/**
* 成功宣告
*/
function resolve(res) {
// 这段还是不理解
// if (res && (typeof res === 'object' || typeof res === 'function')) {
// var then = res.then
// if(typeof then === 'function') {
// then.call(res, resolve)
// return
// }
// }
try {
if (res === self) throw new TypeError('承诺本身不能当做承诺的结果返回给自己');
state = true
resource = res
finale()
} catch(e) {
reject(e)
}
}
/**
* 失败宣告
*/
function reject(res) {
state = false
resource = res
finale()
}
/**
* 最终
*
* 无论成功还是失败 执行当前Promise的所有回调函数
*/
function finale() {
for (var i = 0, len = deferreds.length; i < len; i++) handle(deferreds[i])
deferreds = null
}
// 把两个宣告传给使用者 让使用者自己告诉我什么时候执行什么通告
fn(resolve, reject)
}
// 处理函数要使用的对象
function Handler(onFulfilled, onRejected, resolve, reject) {
this.onFulfilled = typeof onFulfilled === "function" ? onFulfilled : null
this.onRejected = typeof onRejected === "function" ? onRejected : null
resolve = resolve
reject = reject
}
这算是比较基础版的实现吧,我看Promise源码的时候,还有asap库的使用,不过我还不认识asap,就先没用
最后说明:
一、Promise是为了解决回调地狱的问题
二、Promise是一个解决方案(思路),潜在意思就是可以通用(JS,PHP,JAVA),不过必要性就各异了
三、当前代码基于JS写的,而且特意没用什么特性,什么箭头函数,默认参数值什么的,所以是通用的,换句话,就是可以放在小程序里实现微信小程序的同步请求。