共计 5400 个字符,预计需要花费 14 分钟才能阅读完成。
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') |
正文完
发表至: javascript
2020-06-07