简体   繁体   English

处理对异步 function 的多个调用

[英]Handle multiple calls to async function

I have a imported component, she calls a function every time that user do something (lets say press on button), in the function i must to fetch some data in async order, i would like to run the function calls as async way, the calls to the function will wait until the function is finished and then call the function again. I have a imported component, she calls a function every time that user do something (lets say press on button), in the function i must to fetch some data in async order, i would like to run the function calls as async way, the对 function 的调用将等到 function 完成,然后再次调用 function。 code example- if i trigger the function 3 times fast:代码示例-如果我快速触发 function 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}>)
    }

Expected results预期成绩

11111
22222
3333
4444
1111
2222
3333 
4444
1111
2222
3333 
4444

What i get我得到了什么

1111
1111
2222
2222
1111
3333
2222
4444
3333
3333
4444
4444

I use JavaScript- React for the client我为客户端使用 JavaScript-React

What's happening is that multiple changes are happening at once.正在发生的事情是多个变化同时发生。 An easy fix is to set a global flag to prevent the event method while the current action is in-progress.一个简单的解决方法是设置一个全局标志以在当前操作正在进行时阻止事件方法。

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;
  }
};

Edit: Helper class example编辑:助手 class 示例

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;

Using Helper使用助手

// 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));

Thanks to @Proximo i thought about this solution and it's works fine.感谢@Proximo,我想到了这个解决方案,它运行良好。 Maybe someone else will find it helpful so i share my code:)也许其他人会觉得它有帮助,所以我分享我的代码:)

  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}>)
      }

Edit编辑

As a help function作为帮助 function

 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;
    }
  };
};

In your class you call it this way-在你的 class 你这样称呼它-

 constructor(props) {
    super(props);
    this.handleMultiCalls = handleMultiAsyncCalls(blablaFunc);

  handleChange = (data: string) => {
    this.handleMultiCalls(data);
  };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM