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

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

问题描述

最后 async/await 将是 支持 除了 IE 之外的所有主要浏览器.所以现在我们可以使用 async/await 开始编写更具可读性的代码,但有一个问题.很多人像这样使用异步等待:

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 具有 fail-fast 行为,这意味着一旦其中一个承诺被拒绝,它就会拒绝.可能您想要一个更强大的解决方案,我们负责处理任何提取的拒绝.幸运的是有一个解决方案,它可以通过 async/await 来实现,而无需使用 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/await 启用 以运行此代码段(或 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天全站免登陆