从零开始手写promise(一)
上次总结了promise A+ 规范,其实js中的promise只是实现了这个规范。就像js这个语言实现了es的规范一个道理。
带着大家一起手写promise,让我们可以更透彻的理解promise。
今天分享第一步,实现一个工具函数,为后面手写promise服务。
一个是add方法,可以添加函数到队列里,一个是statrup方法,它从工具函数里面拿到函数去依次执行。
因为resove本身也是从函数队列里去拿出来函数执行。
实现一个container工具函数
再加一些需求,如果创建实例的时候添加一些特殊的字段,会有特殊的功能:
stopOnFalse:如果有一个回调函数返回false,则后续的函数不执行
let p = container('stopOnFalse')let fn1 = function(){console.log(1)return false}let fn2 = function(){console.log(2)}p.add(fn1,fn2)p.startup()
once:重复调用的话只执行第一次
let p = container('once')let fn1 = function(){console.log(1)return false}let fn2 = function(){console.log(2)}p.add(fn1,fn2)p.startup()p.startup()
memory:实力化以后添加函数立即执行
let p = container('memory')let fn1 = function(){console.log(1)return false}let fn2 = function(){console.log(2)}p.add(fn1,fn2)p.startup()p.add(function(){console.log(3)})
具体实现代码在这里:纯粹干货
let cache = {} // 缓存对象
let container = function(flags){flags = typeof flags === 'string' ? (cache[flags] || createFlags(flags)):extend({},flags)let carryOut = falselet stack = []let memory = falselet stackLen,stackPoint = 0let fire = function(data){let len = stack.length;let i = stackPoint || 0stackPoint = 0memory = flags.memory && data // flags.memory存在就把data 赋值给变量memorycarryOut = truefor(;i<len;i++){if(stack[i].apply(data[0],data[1]) === false && flags.stopOnFalse){break}}}let obj = {add:function(){(function(args){stackLen = stack.lengthArray.from(args).forEach(item=>{if(toString.call(item) === '[object Function]'){if(!obj.has(item)){stack.push(item)}}else{throw new Error('请正确传参数')}})})(arguments)if(memory){stackPoint = stackLenfire(memory)}},startBind(context,args){args = args || []args = [context,args]if(!flags.once || !carryOut){fire(args)}},startup(){obj.startBind(this,arguments)},has(fn){return stack.indexOf(fn) > -1}}return obj
}
// (flags.match(/\S+/g) 是根据空格去分割字符串为数组
function createFlags(flags){let res = {}
let arr = flags.match(/\S+/g) || []
arr.forEach(item =>{res[item] = true
})return res
}
function extend(to,from){for(let key in from){to[key] = from[key]}return to
}