Callback
场景一:
在微信小程序中,我们对请求做了一层封装,如果请求时,检测到没有 token
或者token
已过期,则需要重新调用 刷新 token
方法,更新 token
后再去请求,然而我们打开微信小程序首页,此时可能并发多个请求,就会出现多次请求刷新 token
方法,我们 需求 是:在第一个请求刷新 token 后再执行后面的业务请求
模拟代码:
function requestA(){setTimeout(()=>{console.log('requestA')
},1000)
}
function requestB(){setTimeout(()=>{console.log('requestB')
},800)
}
function requestC(){setTimeout(()=>{console.log('requestC')
},600)
}
function requestD(){setTimeout(()=>{console.log('requestD')
},400)
}
function requestE(){setTimeout(()=>{console.log('requestE')
},200)
}
requestA 改造:
// 对 requestA 进行 回调 改变
function requestA(callback){setTimeout(()=>{console.log('requestA')
callback && callback()},1000)
}
执行:
requestA(()=>{requestB()
requestC()
requestD()
requestE()})
场景二:
多个请求逐层向上依赖上个请求的数据
示例:
function requestA(callback){setTimeout(()=>{callback && callback('requestA 请求的结果')
},1000)
}
function requestB(ret,callback){if(ret === 'requestA 请求的结果'){setTimeout(()=>{callback && callback('requestB 请求的结果')
},800)
}
}
function requestC(ret,callback){if(ret === 'requestB 请求的结果'){setTimeout(()=>{callback && callback('requestC 请求的结果')
},600)
}
}
function requestD(ret,callback){if(ret === 'requestC 请求的结果'){setTimeout(()=>{callback && callback('requestD 请求的结果')
},400)
}
}
function requestE(ret,callback){if(ret === 'requestD 请求的结果'){setTimeout(()=>{callback && callback('requestE 请求的结果')
},200)
}
}
执行:
requestA(ret=>{console.log(ret)
requestB('requestA 请求的结果',ret=>{console.log(ret)
requestC('requestB 请求的结果',ret=>{console.log(ret)
requestD('requestC 请求的结果',ret=>{console.log(ret)
requestE('requestD 请求的结果',ret=>{console.log(ret)
})
})
})
})
})
依次打印出了:
requestA 请求的结果 ->requestB 请求的结果 ->requestC 请求的结果 ->requestD 请求的结果 ->requestE 请求的结果
Promise
场景:多个请求逐层向上依赖上个请求的数据,用 promise
改造
function requestA(){return new Promise((resolve,reject)=>{setTimeout(()=>{resolve('requestA 请求的结果')
},1000)
})
}
function requestB(param){return new Promise((resolve,reject)=>{if(param==='requestA 请求的结果'){setTimeout(()=>{resolve('requestB 请求的结果')
},800)
}else{reject('requestB 请求失败')
}
})
}
function requestC(param){return new Promise((resolve,reject)=>{if(param==='requestB 请求的结果'){setTimeout(()=>{resolve('requestC 请求的结果')
},600)
}else{reject('requestC 请求失败')
}
})
}
function requestD(param){return new Promise((resolve,reject)=>{if(param==='requestC 请求的结果'){setTimeout(()=>{resolve('requestD 请求的结果')
},400)
}else{reject('requestD 请求失败')
}
})
}
function requestE(param){return new Promise((resolve,reject)=>{if(param==='requestD 请求的结果'){setTimeout(()=>{resolve('requestE 请求的结果')
},200)
}else{reject('requestE 请求失败')
}
})
}
使用:
requestA()
.then(ret=>requestB(ret))
.then(ret=>requestC(ret))
.then(ret=>requestD(ret))
.then(ret=>requestE(ret))
.then(ret=>{console.log(ret)//requestE 请求的结果
}).catch(err=>{console.log(err)
})
Generator
模拟请求:
function requestA(){return new Promise((resolve,reject)=>{setTimeout(()=>{resolve('requestA 请求的结果')
},1000)
})
}
function requestB(param){return new Promise((resolve,reject)=>{if(param==='requestA 请求的结果'){setTimeout(()=>{resolve('requestB 请求的结果')
},800)
}else{reject('requestB 请求失败')
}
})
}
function requestC(param){return new Promise((resolve,reject)=>{if(param==='requestB 请求的结果'){setTimeout(()=>{resolve('requestC 请求的结果')
},600)
}else{reject('requestC 请求失败')
}
})
}
function requestD(param){return new Promise((resolve,reject)=>{if(param==='requestC 请求的结果'){setTimeout(()=>{resolve('requestD 请求的结果')
},400)
}else{reject('requestD 请求失败')
}
})
}
function requestE(param){return new Promise((resolve,reject)=>{if(param==='requestD 请求的结果'){setTimeout(()=>{resolve('requestE 请求的结果')
},200)
}else{reject('requestE 请求失败')
}
})
}
Generator
的异步使用:
function* gen(){let result = yield requestA();
// console.log(result+'result')
let result1 = yield requestB(result);
// console.log(result1+'result1')
let result2 = yield requestC(result1);
// console.log(result2+'result2')
let result3 = yield requestD(result2);
// console.log(result3+'result3')
let result4 = yield requestE(result3);
// console.log(result4+'result4')
return result4
}
var g = gen();
var result = g.next();
result.value.then(function(data){console.log(data+'requestA 请求的数据')
return g.next(data).value
}).then(function(data){console.log(data+'requestB 请求的数据')
return g.next(data).value
}).then(function(data){console.log(data+'requestC 请求的数据')
return g.next(data).value
}).then(function(data){console.log(data+'requestD 请求的数据')
return g.next(data).value
}).then(function(data){console.log(data+'requestE 请求的数据')
})
Async
模拟请求:
function requestA(){return new Promise((resolve,reject)=>{setTimeout(()=>{resolve('requestA 请求的结果')
},1000)
})
}
function requestB(param){return new Promise((resolve,reject)=>{if(param==='requestA 请求的结果'){setTimeout(()=>{resolve('requestB 请求的结果')
},800)
}else{reject('requestB 请求失败')
}
})
}
function requestC(param){return new Promise((resolve,reject)=>{if(param==='requestB 请求的结果'){setTimeout(()=>{resolve('requestC 请求的结果')
},600)
}else{reject('requestC 请求失败')
}
})
}
function requestD(param){return new Promise((resolve,reject)=>{if(param==='requestC 请求的结果'){setTimeout(()=>{resolve('requestD 请求的结果')
},400)
}else{reject('requestD 请求失败')
}
})
}
function requestE(param){return new Promise((resolve,reject)=>{if(param==='requestD 请求的结果'){setTimeout(()=>{resolve('requestE 请求的结果')
},200)
}else{reject('requestE 请求失败')
}
})
}
Async
的异步使用:
async function init(){let ret1 =await requestA()
let ret2 =await requestB(ret1)
let ret3 =await requestC(ret2)
let ret4 =await requestD(ret3)
let ret5 =await requestE(ret4)
return ret5
}
init().then(res=>{console.log(res)//requestE 请求的结果
}).catch(err=>{console.log(err)
})
事件监听
脚本的执行不取决代码的顺序,而取决于某一个事件是否发生。
案列:
$(document).ready(function(){console.log('DOM 已经 ready')
});
发布 / 订阅
发布 / 订阅模式是利用一个消息中心,发布者发布一个消息给消息中心,订阅者从消息中心订阅该消息
案例:
// 订阅 done 事件
$('#box').on('done',function(data){console.log(data)
})
// 发布事件
$('#box').trigger('done,'data')