嵌套异步/等待是一种反模式吗?

时间:2019-08-05 08:18:30

标签: javascript reactjs asynchronous promise

我有getAction1、2和3函数,它们在后端API服务中执行一些操作。

我需要有一个依次执行getAction1、2和3的按钮。

在这种情况下,

这样做更好吗? (OPTION.1)

apiconsumer.js

export const getAction1 = (param1) => new Promise(
    function (resolve, reject) {
      // DO SOMETHING AND RETURN 'resolve' or 'reject'
    });
export const getAction2 = (param2) => new Promise(
    function (resolve, reject) {
      // DO SOMETHING AND RETURN 'resolve' or 'reject'
    });
export const getAction3 = (param3) => new Promise(
    function (resolve, reject) {
      // DO SOMETHING AND RETURN 'resolve' or 'reject'
    });

button.js

const handleOnClick = async (event) => {

    const response1 = await getAction1(param1);
    const response2 = await getAction2(param2);
    const response3 = await getAction3(param3);

// DO SOMETHING...

  };

还是这样做? (OPTION.2)

apiconsumer.js

export const getAction1 = (param1) => new Promise(
    function (resolve, reject) {
      // DO SOMETHING AND RETURN 'resolve' or 'reject'
    });
export const getAction2 = (param2) => new Promise(
    function (resolve, reject) {
      // DO SOMETHING AND RETURN 'resolve' or 'reject'
    });
export const getAction3 = (param3) => new Promise(
    function (resolve, reject) {
      // DO SOMETHING AND RETURN 'resolve' or 'reject'
    });

export const performActions =  async (uData) => {
    const response1 = await getAction1(uData.param1);
    const response2 = await getAction2(uData.param2);
    const response3 = await getAction3(uData.param3);

    };

button.js

const handleOnClick = async (event) => {

    const response1 = await performActions(uData);

// DO SOMETHING...

  };

基本上,OPTION.2创建一个嵌套的异步/等待函数。

我不确定像上面的OPTION.2一样嵌套异步/等待是否是一个好主意。如果这些都不是好事,您有什么建议?

2 个答案:

答案 0 :(得分:4)

全部使用承诺

如果结果不相互依赖。

await Promise.all([
  getAction1(uData.param1),
  getAction2(uData.param2);,
  getAction3(uData.param3);
])

答案 1 :(得分:1)

对我来说,很明显地要从“视图”中抽象出尽可能多的业务逻辑。在这种情况下,您的按钮似乎是“视图”。对动作1、2、3是否异步并不重要,对我而言,它们属于处理业务逻辑而不是显示的某一层。

“嵌套”(或更确切地说是“集合”)async/await是否优雅并不重要,因为您肯定可以。大多数复杂的前端API都以这种方式工作,您肯定应该这样做。

但是,是否应该在apiconsumer中声明之后或在其他某个级别上对它们进行汇总取决于您所实现的特定功能。

问问自己:

  1. performActions函数作为一个“操作”有意义吗?如果您可以轻松地命名-肯定是这样。
  2. performActions是否与apiconsumer中的其他功能相关?似乎更抽象了,所以也许可以在这两个位置之间有一个中间层,例如“服务”或“控制器”?我猜您将apiconsumer设计为只是端点和基本调用的列表,最好不要使用更复杂的函数对其进行污染。
  3. 事件侦听器是否会捕获错误(拒绝)?如果是这样,可以将所有3个异常组合到一个处理程序中吗?

总的来说,对我来说,总是可以将我的应用程序划分为“ sorta MVC”层:

  1. 查看即显示-您的组件和DOM操作
  2. 模型-api调用-尽可能愚蠢;加上一些不可避免的数据格式化逻辑
  3. 控制器-其他所有内容,需要计算的内容,需要同步的调用等。

这只是基本概念,您可以根据需要对其进行调整和使用。

您还可以使用一些现成的架构,例如redux,mobx等。如果您不想被那些“框架”所困扰,您至少可以从如何构造事物上汲取灵感。 / p>