Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【node实战系列】异步并发,自定义Promise.allSettled #56

Open
yeyeye0525 opened this issue Jul 12, 2021 · 0 comments
Open

Comments

@yeyeye0525
Copy link
Contributor

yeyeye0525 commented Jul 12, 2021

file

本文首发于:https://github.com/bigo-frontend/blog/ 欢迎关注、转载。

背景

bigo前端开始推广bff,hello农场作为首个bff落地项目,历经2个月,完成了从0-1的落地实践。

【node实战系列】按照小模块拆分,从开发者的角度讲叙,如何进行bff高可用编码。

本系列文章,基于eggjs框架编码,使用ts语法,为了提升阅读体验,建议大家先了解一下eggjs。

系列文章

欢迎大家关注我们的github blog,持续更新。
https://github.com/bigo-frontend/blog/issues

请求并发

由于nodejs事件循环的实现,让异步编程变得简单。

我们可以直接使用Promise对象进行异步调用。bff的一个核心场景就是接口聚合,自然离不开多个接口并发请求。

请求并发可以让我们把请求时间缩短为当前最长请求的时间。

举个例子:需要聚合a、b、c三个接口,对应的接口响应时间为100ms、150ms、200ms,如果是顺序请求,聚合耗时450ms,
但是使用请求并发,聚合耗时200ms,收益是十分明显的。

Promise.allSettled

Promise.all:短路特性,有一个请求错误,直接走catch,不再走then。
Promise.allSettled : 无论请求对错最终都会返回一个数组对象到then中,并切返回的数据中标识了错误跟正确数据的区别。
但是属于新的提案,有需要nodejs>=12.9.0,我们的测试环境还使用v10版本,所以需要我们手动封装一下。

image.png

自定义Promise.allSettled

实现

// 请求并发,相当于Promise.allSettled
allSettled(promises) { // 自定义 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled
  return new Promise(resolve => {
    const data: any = [], len = promises.length;
    let count = len;
    for (let i = 0; i < len; i += 1) {
      const promise = promises[i];
      promise.then(res => {
        data[i] = res;
      }, error => {
        data[i] = error;
      }).finally(() => { // promise has been settled
        if (!--count) {
          resolve(data);
        }
      });
    }
  });
}

业务使用示例

const resList = await ctx.helper.allSettled([
  // 1.我的农场信息
  service.accounts.getAccountInfoByUid.request(),
  // 2.用户信息
  service.accounts.getUserExtraInfo.requestByUid(),
  // 3.是否大客户
  service.accounts.getBigClient.request(),
  // 4.是否显示礼包红点
  service.gift.checkAppTabIsNeedShowRedPoint.request(),
  // 5.今天是否签到
  service.task.signHistory.isSignedToday(),
  // 6.个人形象集合
  service.accounts.getAccountAppearanceInfo.getAppearanceList(),
  // 7.我的形象
  service.accounts.getAccountAppearanceInfo.appearanceInfo(),
  // 8.礼包列表
  service.gift.getGiftList.request(),
  // 9.任务红点
  service.task.listCommonTask.isShowTaskRedPoint()
]);

小结

综上,一个简单又实用的请求并发功能就实现了。

欢迎大家留言讨论,祝工作顺利、生活愉快!

我是bigo前端,下期见。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant