【问题标题】:Javascript moving my Node6 Firebase function to Node8 async/await patternJavascript 将我的 Node6 Firebase 函数移动到 Node8 异步/等待模式
【发布时间】:2019-05-01 18:10:08
【问题描述】:

由于 firebase 函数现在使用 Node8 运行,我想将我当前的 ES5 函数 w Promise 流转换为 ES6 async/await

我的流程模式如下:

const AUTHORIZED = authorizedApi()
  if AUTHORIZED
      const SENT = sendContactMessage())
      if SENT
          const FOUND = findContact(
              if FOUND
                  return "FINISHED"
                  if !FOUND
                      const CREATED = createContact()
                      if CREATED
                          return "FINISHED"

目前我正在使用一个特定的 conditionalPromiseFlow() 函数,如下所示:( 还需要处理错误..

const conditionalPromiseFlow = (...fns) => {
  if (fns.length === 0) return Promise.resolve();
  const [next] = fns;
  return next().then(result => {
    if (result) {
      return conditionalPromiseFlow(...fns.slice(1));
    }
    return result;
  });
};

我称之为:

conditionalPromiseFlow(
  () => authorizedApi(jwtClient),
  () => sendContactMessage(gmailAPI, encodedContactMessage),
  () =>
    findContact(
      googlePeopleAPI.connections,
      googleConnectionListParams,
      sender.email
    ),
  () => createContact(googlePeopleAPI, googlePeopleContactParams)
)
  .then(
    res => {
      return { status: 200, infos: "done" };
    },
    error => {
      return { status: error.status, infos: error.message };
    }
  )
  .then(response => {
    return res.send(response);
  })
  .catch(console.error);

这运行良好,但我猜异步/等待模式会简化我的代码...这是真的还是我应该坚持我当前的代码?

感谢反馈

【问题讨论】:

    标签: javascript promise async-await


    【解决方案1】:

    假设这包含在 async 函数中,async/await 等效项将是:

    (async() => {
      try {
        await authorizedApi(jwtClient);
        await sendContactMessage(gmailAPI, encodedContactMessage);
        await findContact(
          googlePeopleAPI.connections,
          googleConnectionListParams,
          sender.email
        );
        await createContact(googlePeopleAPI, googlePeopleContactParams);
        res.send({ status: 200, infos: "done" });
      } catch (error) {
        res.send({ status: error.status, infos: error.message });
      }
    ))();
    

    这是否更简单以及是否值得做出改变显然取决于您。

    (从您的代码中,当这些函数返回的承诺拒绝时,我接受它,它们提供的对象上有一个status。)

    请注意,我没有在最后一个 res.send 周围添加 try/catch。我不认为它会抛出,但你确实有一个 catch 处理程序。所以如果它抛出,你会想把它放回去。

    如果您已经async 函数中,显然您不需要 async 包装器:

    try {
      await authorizedApi(jwtClient);
      await sendContactMessage(gmailAPI, encodedContactMessage);
      await findContact(
        googlePeopleAPI.connections,
        googleConnectionListParams,
        sender.email
      );
      await createContact(googlePeopleAPI, googlePeopleContactParams);
      res.send({ status: 200, infos: "done" });
    } catch (error) {
      res.send({ status: error.status, infos: error.message });
    }
    

    res.send 看来您正在使用 express 框架 - 所以您可以将处理程序作为异步包装器,将 async 放在 (req, res) 之前就足够了:

    app.get('/something', async (req, res) => {
      try {
        /*
        await stuff here
        */
        res.send({ status: 200, infos: "done" });
      } catch (error) {
        res.send({ status: error.status, infos: error.message });
      }
    });
    

    请注意,在上述和第一个代码块中的async 包装器中,整个 主体都在try 中(res.send 出错)。这是因为没有任何东西可以处理来自async 函数的承诺(Express 不会对路由回调的返回值做任何事情),所以重要的是承诺不会拒绝。

    【讨论】:

    • 非常感谢!我现在对它有了更好的理解......(你的权利,我正在使用一个快速框架......当用户发送联系人请求时会请求这个 HTTP Firebase 函数......它会触发一些 Google API 函数...... gmail将消息发送给管理员,然后检查联系人是否已存在于 Firebase DB 中,如果不存在则创建它...
    • @erwin - 我没有也可以说应该指出koajs.com,这是与 Express 相同的人开发的新框架,它在框架级别合并了 async 功能。
    猜你喜欢
    • 2019-11-17
    • 1970-01-01
    • 2020-03-05
    • 2017-11-10
    • 2011-03-04
    • 2016-02-16
    • 2022-01-01
    • 2021-04-16
    • 2022-07-06
    相关资源
    最近更新 更多