How run async / await in parallel in Javascript

后端 未结 6 982
没有蜡笔的小新
没有蜡笔的小新 2020-11-30 17:16

Finally async/await will be supported in all major browser soon except IE. So now we can start writing more readable code with async/<

6条回答
  •  旧时难觅i
    2020-11-30 17:52

    You can write something like this:

    const responses = await Promise.all([
     fetchUserAsync(),
     fetchPostsAsync(),
    ]);
    
    const userResponse = responses[0];
    const postsResponse = responses[1];
    

    This is easy right? But there is a catch. Promise.all has fail-fast behaviour which means, it will reject as soon as one of the promises rejected. Probably you want a more robust solution where we are in charge of handling the rejections any of the fetches. Luckily there is a solution, it can be achieved simply with async/await without the need of using Promise.all. A working example:

    console.clear();
    
    function wait(ms, data) {
      return new Promise( resolve => setTimeout(resolve.bind(this, data), ms) );
    }
    
    /** 
     * This will run in series, because 
     * we call a function and immediately wait for it's result, 
     * so this will finish in 1s.
     */
    async function series() {
      return {
        result1: await wait(500, 'seriesTask1'),
        result2: await wait(500, 'seriesTask2'),
      }
    }
    
    /** 
     * While here we call the functions first,
     * then wait for the result later, so 
     * this will finish in 500ms.
     */
    async function parallel() {
      const task1 = wait(500, 'parallelTask1');
      const task2 = wait(500, 'parallelTask2');
    
      return {
        result1: await task1,
        result2: await task2,
      }
    }
    
    async function taskRunner(fn, label) {
      const startTime = performance.now();
      console.log(`Task ${label} starting...`);
      let result = await fn();
      console.log(`Task ${label} finished in ${ Number.parseInt(performance.now() - startTime) } miliseconds with,`, result);
    }
    
    void taskRunner(series, 'series');
    void taskRunner(parallel, 'parallel');
    
    
    /* 
     * The result will be:
     * Task series starting...
     * Task parallel starting...
     * Task parallel finished in 500 milliseconds with, { "result1": "parallelTask1", "result2": "parallelTask2" }
     * Task series finished in 1001 milliseconds with, { "result1": "seriesTask1", "result2": "seriesTask2" }
     */

    Note: You will need a browser which has async/await enabled to run this snippet (or nodejs v7 and above)

    This way you can use simply try/ catch to handle your errors, and return partial results inside the parallel function.

提交回复
热议问题