如何在Javascript中并行运行async / await [英] How run async / await in parallel in Javascript

查看:110
本文介绍了如何在Javascript中并行运行async / await的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最后 async / 等待支持
所以现在我们可以用 async / await 开始编写更易读的代码但是有一个问题。很多人都像这样使用async:

Finally async/await will be supported in all major browser soon except IE. So now we can start writing more readable code with async/await but there is a catch. A lot of people use async await like this:

const userResponse = await fetchUserAsync();
const postsResponse = await fetchPostsAsync();

虽然这段代码是可读的但它有问题,它会串行运行函数,它不会开始提取帖子,直到完成用户的提取。解决方案很简单,我们需要并行获取资源。

While this code is readable it has a problem, it runs the functions in series, it won't start fetching posts until the fetching of the user is finished. The solutions is simple, we need to fetch the resources in parallel.

所以我想做的是(伪语言):

So what I want to do is (in pseudo language):

fn task() {
  result-1 = doAsync();
  result-2 = doAsync();
  result-n = doLongAsync();

  // handle results together
  combinedResult = handleResults(result-1, result-2);

  lastResult = handleLastResult(result-n);
}


推荐答案

你可以写这样的东西:

const responses = await Promise.all([
 fetchUserAsync(),
 fetchPostsAsync(),
]);

const userResponse = responses[0];
const postsResponse = responses[1];

这很容易吗?但是有一个问题! Promise.all 具有快速失败行为,这意味着,只要其中一个承诺被拒绝,它就会拒绝。可能你想要一个更强大的解决方案,我们负责处理任何提取的拒绝。幸运的是有一个解决方案,只需使用 async / 等待即可实现,而无需使用 Promise.all 。一个工作示例:

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" }
 */

注意:您需要一个具有 async / 等待的浏览器 已启用以运行此代码段(或nodejs v7及以上版本)

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

这样你就可以使用 try / catch 处理您的错误,并在 parallel 函数内返回部分结果。

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

这篇关于如何在Javascript中并行运行async / await的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆