【问题标题】:How do I deal with async for a response in a callback function?如何在回调函数中处理异步响应?
【发布时间】:2021-11-21 14:59:39
【问题描述】:

我正在使用 this 包作为 API 包装器,以便在无服务器函数中与 CampaignMonitor API 进行交互。目的是向无服务器函数的调用者返回响应,确认将订阅者添加到 CampaignMonitor 的操作是否成功。

这是我目前所拥有的:

exports.handler = async (event, context) => {
  const body = JSON.parse(event.body);

  // set request details
  const listId = process.env.CM_LIST_ID;
  const details = body;

  // Send Request and check for error returned
  api.subscribers.addSubscriber(listId, details, (err, res) => {
    if (err) {
      return {
        statusCode: 400,
        body: JSON.stringify({ message: err }),
      };
    } else {
      return {
        statusCode: 200,
        body: JSON.stringify({ message: 'success' }),
      };
    }
  });
};

不幸的是,这不起作用,我认为由于没有等待对发送请求的最后部分的响应这一事实。我有点不确定如何处理它,它是一个回调函数。

我已经使用这段代码一段时间了,如果没有错误,订阅者将被添加到订阅者列表中,并且当第二个返回语句超出时,无服务器函数会返回成功响应回调(在 api.subscribers.addSubscriber 下面)。

【问题讨论】:

    标签: javascript node.js async-await promise


    【解决方案1】:

    问题

    api.subscribers.addSubscriber 的回调函数返回值不会使其成为包装器handler 函数的返回值。

    解决方案

    由于您使用的库不提供基于 Promise 的 API,您可以围绕它创建一个 Promise 包装器并使用它来获得所需的结果。

    在 nodeJS 中创建一个 Promise 包装器的最简单方法是使用内置的 util 模块。

    const util = require("util");
    
    const promisifedAddSubscriber = util.promisify(api.subscribers.addSubscriber);
    

    一旦你有了一个基于 Promise 的 api.subscribers.addSubscriber 函数,你就可以 await 调用这个函数。

    exports.handler = async (event, context) => {
      try {
        ...
    
        // explicitly bind "this"
        const result = await promisifedAddSubscriber.bind(api.subscribers)(listId, details);
      
        return {
          statusCode: 200,
          body: JSON.stringify({ message: 'success' }),
        };
      }
      catch (error) {
        return {
          statusCode: 400,
          body: JSON.stringify({ message: error }),
        };
      }
    };
    

    【讨论】:

    • 我仍然遇到这个问题,我现在收到一个错误“无法读取'node_modules/createsend-node/lib/interface/subscribers.js'中未定义的属性'post' :12:20" 似乎与创建端节点 API 包装器有关?
    • 这可能是因为 this 的值不正确。尝试显式绑定 this 的值:await promisifedAddSubscriber.bind(api.subscribers)(listId, details)
    • 恐怕还是不行。我收到有效输入返回的错误,它也没有给我之前在回调函数中收到的详细错误消息(即:电子邮件地址已存在于列表中)当我控制台记录来自 catch 的错误时,我'我得到相同的'无法读取未定义的属性'post''
    • 问题肯定是因为incorrect value of this。您是否尝试过绑定this,如上述评论所示?您能否编辑您的问题以包含更新后的代码?
    • @Roamer-1888 同意。
    【解决方案2】:

    在下面找到 async-await 的工作实现:

    exports.handler = async (event, context) => {
      try
      {
          const body = JSON.parse(event.body);
    
          // set request details
          const listId = process.env.CM_LIST_ID;
          const details = body;
        
          const result = await api.subscribers.addSubscriber(listId, details);
          return {
            statusCode: 200,
            body: JSON.stringify({ message: 'success' }),
          };
      }
      catch(err){
          return {
          statusCode: 400,
          body: JSON.stringify({ message: err }),
        };
      }
    };
    

    【讨论】:

    • 感谢您的回复,但这不起作用。我收到错误“回调不是函数”,可能是因为回调是必需的,但此版本的代码中缺少回调
    • 在这种情况下,请在 addSubscriber 函数中进行更正。现在问题在于该功能。你能把那段代码发过来吗
    【解决方案3】:

    您需要从check_saved_url 返回一个Promise。在 Promise 内部,您需要使用 resolve 替换 return。如果出现错误,您也可以使用reject(new Error("error"))

    您可以在 MDN 上阅读更多关于 Promise 的信息

    exports.handler = async(event, context) => {
        return new Promise((resolve, reject) => {
            const body = JSON.parse(event.body);
    
            // set request details
            const listId = process.env.CM_LIST_ID;
            const details = body;
    
            // Send Request and check for error returned
            api.subscribers.addSubscriber(listId, details, (err, res) => {
                if (err) {
                  reject(new Error({
                      statusCode: 400,
                      body: JSON.stringify({
                        message: err
                      })
                    }));
                  } else {
                    resolve({
                      statusCode: 200,
                      body: JSON.stringify({
                        message: 'success'
                      })
                    });
                  }
                });
            });
        };

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-08-07
      • 2015-06-20
      • 2017-06-13
      • 1970-01-01
      • 2023-02-02
      • 1970-01-01
      • 2020-11-22
      相关资源
      最近更新 更多