处理对异步函数的多个调用
2020-04-18
378
我有一个导入的组件,每次用户执行某项操作(比如说按下按钮)时,它都会调用一个函数,在函数中我必须以异步顺序获取一些数据,我想以异步方式运行函数调用,对函数的调用将等到函数完成后再调用该函数。 代码示例 - 如果我快速触发该函数 3 次:
hadlechange = async(type:string) => {
console.log(1111111)
let storage = await getData("G");
console.log(22222222)
await bla1();
await bla2();
console.log(333333)
await storeData('blabla');
console.log(4444444)
};
render() {
return (
<BlaBla onChange ={this.hadlechange}>)
}
预期结果
11111
22222
3333
4444
1111
2222
3333
4444
1111
2222
3333
4444
我得到的
1111
1111
2222
2222
1111
3333
2222
4444
3333
3333
4444
4444
我使用 JavaScript- React 作为客户端
2个回答
感谢@Proximo,我考虑过这个解决方案,它运行良好。 也许其他人会觉得它有用,所以我分享了我的代码 :)
constructor() {
this.notHandling = true;
this.saves = [];
}
onChange = async (status: string) => {
this.saves.push(status);
if (this.notHandling) {
this.notHandling = false;
while (saves.length > 0) {
await blabla1(saves.pop());
...
}
this.notHandling = true;
}
};
render() {
return (
<BlaBla onChange ={this.hadlechange}>)
}
编辑
作为帮助功能
export const handleMultiAsyncCalls = func => {
let notHandling = true;
let saves = [];
return async function() {
const args = arguments;
const context = this;
saves.push(args);
if (notHandling) {
notHandling = false;
while (saves.length > 0) {
await func.apply(context, saves.pop());
}
notHandling = true;
}
};
};
在你的课堂上你这样称呼它-
constructor(props) {
super(props);
this.handleMultiCalls = handleMultiAsyncCalls(blablaFunc);
handleChange = (data: string) => {
this.handleMultiCalls(data);
};
Barak
2020-04-18
实际发生的情况是多个更改同时发生。一个简单的解决方法是设置一个全局标志,以在当前操作正在进行时阻止事件方法。
constructor() {
this.notHandling = true;
}
hadlechange = async(type:string) => {
if (this.notHandling) {
this.notHandling = false;
console.log(1111111)
let storage = await getData("G");
console.log(22222222)
await bla1();
await bla2();
console.log(333333)
await storeData('blabla');
console.log(4444444)
this.notHandling = true;
}
};
编辑:帮助程序类示例
class AsyncQueue {
private queue: Function[];
private processing: boolean;
constructor() {
this.queue = [];
this.processing = false;
}
push = (method:any) => {
this.queue.push(method);
this.process();
}
private process = async () => {
if (!this.processing) {
this.processing = true;
for (let action of this.queue) {
await action();
}
this.processing = false;
}
}
}
export const asyncQueue = new AsyncQueue;
使用帮助程序
// import example...
import { asyncQueue } from '~/common/helpers';
// Async test method
const tester = (message: string, seconds: number = 1) => {
return new Promise((resolve) => {
console.log('start ' + message);
setTimeout(() => {
console.log(message);
resolve(message);
}, seconds * 1000);
});
};
// Method calls
asyncQueue.push(() => tester('FIRST'));
setTimeout(() => asyncQueue.push(() => tester('SECOND', 2)), 50);
asyncQueue.push(() => tester('THIRD', 4));
Proximo
2020-04-18