Open CPPAlien opened 4 years ago
我们知道可以用 async await 实现一个函数内的同步执行,如
async function test() { await run(); }
但这并不是全局的同步,因为 JS 是单线程,语言中也没有一个线程锁的概念,如果我们有如下需求,
let tag; async function test() { if (tag) { tag = await 一个请求,请求成功后,会把 tag 变为 true console.log(tag) } else { console.log(tag) } }
大致意思,是想全局请求一个标志记录,而一旦内存中已经有这个 tag 了就不需要重复请求了。
如果此时外部有多个回掉同时调用的话,会导致 tag 并不是全局唯一生成的,不同回调都会卡在 await 那边,跳过 tag 判断。 request1(() => {test()}) request2(() => {test()})
const PENDDING_LIST: (() => Promise<any>)[] = []; let timeOutContext: any; async function test() { const promise = () => { if (tag) { tag = await 一个请求,请求成功后,会把 tag 变为 true console.log(tag) } else { console.log(tag) } } GLOBAL_PENDDING_LIST.push(promise); clearTimeout(timeOutContext); timeOutContext = setTimeout(() => { const penddingList: any = []; GLOBAL_PENDDING_LIST.map(item => { penddingList.push(item); }); GLOBAL_PENDDING_LIST.length = 0; const total = penddingList.length; let count = 0; const run = () => { penddingList[count]().then(() => { count++; if (count >= total) { return; } run(); }); }; run(); }, 500); }
首先把执行包装为 promise 的函数,调用后都放到一个队列中。使用一个 timeout 来执行队列中的 promise,因为会该函数会多次执行,为了只执行最后一次 timeout,需要先 clear 老的,再创建。
我们知道可以用 async await 实现一个函数内的同步执行,如
但这并不是全局的同步,因为 JS 是单线程,语言中也没有一个线程锁的概念,如果我们有如下需求,
大致意思,是想全局请求一个标志记录,而一旦内存中已经有这个 tag 了就不需要重复请求了。
如果此时外部有多个回掉同时调用的话,会导致 tag 并不是全局唯一生成的,不同回调都会卡在 await 那边,跳过 tag 判断。 request1(() => {test()}) request2(() => {test()})
如何实现全局同步
首先把执行包装为 promise 的函数,调用后都放到一个队列中。使用一个 timeout 来执行队列中的 promise,因为会该函数会多次执行,为了只执行最后一次 timeout,需要先 clear 老的,再创建。