上次总结了promise A+ 规范,其实js中的promise只是实现了这个规范。就像js这个语言实现了es的规范一个道理。
带着大家一起手写promise,让我们可以更透彻的理解promise。
今天分享第一步,实现一个工具函数,为后面手写promise服务。
一个是add方法,可以添加函数到队列里,一个是statrup方法,它从工具函数里面拿到函数去依次执行。
因为resove本身也是从函数队列里去拿出来函数执行。
再加一些需求,如果创建实例的时候添加一些特殊的字段,会有特殊的功能:
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 = false
let stack = []
let memory = false
let stackLen,stackPoint = 0
let fire = function(data){
let len = stack.length;
let i = stackPoint || 0
stackPoint = 0
memory = flags.memory && data // flags.memory存在就把data 赋值给变量memory
carryOut = true
for(;i{
if(toString.call(item) === '[object Function]'){
if(!obj.has(item)){
stack.push(item)
}
}else{
throw new Error('请正确传参数')
}
})
})(arguments)
if(memory){
stackPoint = stackLen
fire(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
}