问题:我几乎没有使用异步等待函数的经验,我试图在if-else语句中执行嵌套的异步等待函数,该语句依赖于更高级别的异步函数在事件检测时执行.我希望从嵌套的异步函数返回一个成功的http响应,但我继续为响应获取空值.然而,嵌套的异步函数在if-else语句之外按预期工作.我的目标是简单地让代码中的"等待新promise "部分在条件if-else语句中返回http响应.感谢您的帮助.

我try 过的内容:除了搜索具有类似问题的问题之外,我还没有真正try 过纠正这种情况,因为我对异步等待函数的性质知之甚少.

代码:

 exports.handler = async (event) => {
    
    const sensorId = event.sensorId;
    
    ddb.scan(params, function (err, data) {
  

    if (err) {
    console.log("Error", err);
  } else {
    console.log("Success", data);
    console.log(typeof(data));
    data.Items.forEach(function (item, index, array) {
      console.log("printing", item);
      console.log('Testing', item.sensorId.S);
      
      if (item.sensorId.S == sensorId) {
          console.log('New sensorId was not created. Already Exists.');
          return ;
      }
      else {
    // Here is the nested async await function
    async () => {
    console.log(event.sensorId);
    const req = new AWS.HttpRequest(appsyncUrl, region);

    const item = {
        input: {
            id: event.sensorId,
            sensorId: event.sensorId
        }
    };

    req.method = "POST";
    req.path = "/graphql";
    req.headers.host = endpoint;
    req.headers["Content-Type"] = "application/json";
    req.body = JSON.stringify({
        query: print(createSensor),
        operationName: "createSensor",
        variables: item
    });
    console.log(typeof(graphqlQuery));
    if (apiKey) {
        req.headers["x-api-key"] = apiKey;
    } else {
        const signer = new AWS.Signers.V4(req, "appsync", true);
        signer.addAuthorization(AWS.config.credentials, AWS.util.date.getDate());
    }
    
    
    const data =  await new Promise((resolve, reject) => {
        const httpRequest = https.request({ ...req, host: endpoint }, (result) => {
            let data = "";

            result.on("data", (chunk) => {
                data += chunk;
            });

            result.on("end", () => {
                resolve(JSON.parse(data.toString()));
            });
        });

        httpRequest.write(req.body);
        httpRequest.end();
    });
  
  


try {
    return {
        status代码: 200,
        body: data
    };
}

catch(err) {
    console.log('error', err);
}
      };
      
    }});
  }
});

预期结果:

Response
{
  "statusCode": 200,
  "body": {
    "data": {
      "createSensor": {
        "id": "fd78597a-12fd-4bd1-9f9d-6ee1a88e197d",
        "digit": null,
        "date": null,
        "timestamp": null
      }
    }
  }
}

实际结果:

Response
null

推荐答案

你的代码有几个问题:

  1. 嵌套异步函数——您正在创建它,但从未执行它
async () => { // creates an async anonymous arrow function, that's it

}

两种解决方案:

// wrapping the function in an IIFE create and executes it
(async () => {

})();

// give it a name and execute it later
async main() => {

}

main();
  1. 通过将传递给forEach的回调声明为async,可以摆脱嵌套的async函数:
data.Items.forEach(async (item, index, array) => { // <--- this is async
  // ...

  const req = new AWS.HttpRequest(appsyncUrl, region);
  const item = {
    input: {
      id: event.sensorId,
      sensorId: event.sensorId,
    },
  };

  // ...
});
  1. 末尾的try/catch块不会捕获任何错误.相反,将创建的promise 封装在try/catch块中,并在发生错误事件时从内部拒绝:
try {
  const data = await new Promise((resolve, reject) => {
    const httpRequest = https.request(
      { ...req, host: endpoint },
      (result) => {
        // ...

        result.on("error", (error) => {
          reject(error);
        });

        // ...
      }
    );

    // ...
  });

  return {
    statusCode: 200,
    body: data,
  };
} catch (err) {
  console.log("error", err);
}
  1. 在forEach中运行异步操作并不能达到您的目的.您可能打算响应after所有传感器SID都已创建.真正发生的事情是,当第一个sensorId被创建时,你会立即做出响应.这是因为forEach同时触发data.Items次回调.解决这个问题的一个方法是使用map,并返回一系列promise ,然后您可以带着promise 等待.全部的

下面是最终的代码,以及我将如何解决它.作为一个额外的例子,我promise 了ddb.scan个,所以你不会把回调和promise 以及异步/等待混为一谈:

const scanAsync = util.promisify(ddb.scan);

exports.handler = async (event) => {
  const sensorId = event.sensorId;

  try {
    const data = await scanAsync(params);

    const responses = await Promise.all(
      data.Items.map((item) => {
        if (item.sensorId.S == sensorId) {
          console.log("New sensorId was not created. Already Exists.");
          return;
        }

        const req = new AWS.HttpRequest(appsyncUrl, region);
        const item = {
          input: {
            id: event.sensorId,
            sensorId: event.sensorId,
          },
        };

        req.method = "POST";
        req.path = "/graphql";
        req.headers.host = endpoint;
        req.headers["Content-Type"] = "application/json";
        req.body = JSON.stringify({
          query: print(createSensor),
          operationName: "createSensor",
          variables: item,
        });

        if (apiKey) {
          req.headers["x-api-key"] = apiKey;
        } else {
          const signer = new AWS.Signers.V4(req, "appsync", true);
          signer.addAuthorization(
            AWS.config.credentials,
            AWS.util.date.getDate()
          );
        }

        return new Promise((resolve, reject) => {
          const httpRequest = https.request(
            { ...req, host: endpoint },
            (result) => {
              let data = "";

              result.on("data", (chunk) => {
                data += chunk;
              });

              result.on("error", (error) => {
                reject(error);
              });

              result.on("end", () => {
                resolve(JSON.parse(data.toString()));
              });
            }
          );

          httpRequest.write(req.body);
          httpRequest.end();
        });
      })
    );

    return {
      statusCode: 200,
      body: responses,
    };
  } catch (error) {
    console.log("error", error);
  }
};

我希望你能从我的回答中学到一两件事:).如果你有任何问题,请告诉我.

Javascript相关问答推荐

在Chart.js 4.4.2中移动到不同大小的容器时,图表不会调整大小

使用NgDeliverentOutlet和动态内容投影的Angular 渲染组件

事件错误:类型错误:无法读取未定义的属性(读取stopPropagation)

使用Apps Script缩短谷歌表中的URL?

无法将nPM simplex-noise包导入在JS项目中工作

在nextjs服务器端api调用中传递认证凭证

为什么!逗号和空格不会作为输出返回,如果它在参数上?

如何通过使用vanilla JS限制字体大小增加或减少两次来改变字体大小

使用原型判断对象是否为类的实例

正则表达式,允许我匹配除已定义的子字符串之外的所有内容

Rxjs流中生成IMMER不能在对象上操作

如何在我的Next.js项目中.blob()我的图像文件?

按什么顺序接收`storage`事件?

删除元素属性或样式属性的首选方法

FileReader()不能处理Firefox和GiB文件

使用线性插值法旋转直线以查看鼠标会导致 skip

构建器模式与参数对象输入

如何在脚本编译后直接将RxJ模块导入浏览器(无需Angel、webpack、LiteServer)

JavaScript&;Reaction-如何避免在不使用字典/对象的情况下出现地狱?

Chart.js Hover线条在鼠标离开时不会消失