简体   繁体   English

在解析 promise 之前,Lamda function 调用结束

[英]Lamda function invocation ends before resolving the promise

I have the following code to read a file from a URL and then upload it to another destination:我有以下代码从 URL 读取文件,然后将其上传到另一个目的地:

import request from 'request';
import FormData from 'form-data';

export const handler = async (event, context) => {
  new Promise((resolve, reject) => {
    const form = new FormData();
    console.log('Streaming ...');
    form.append('file', request('https://cdn.mysite.com/video.mp4'));
    console.log('Uploading ...');
    // Invocation ends here!
    form.submit('https://www.someapi.com/upload', (error, response) => {
      if (error) reject(error);
      let body = '';
      response.on('data', chunk => {
        console.log('Receiving response ...');
        body += chunk.toString()
      });
      response.on('end', () => {
        console.log('Done ...');
        resolve(JSON.parse(body))
      });
      response.resume();
    });
  });
};

Running this code locally works fine, but when I deploy and run it on AWS Lambda it ends before submitting the form.在本地运行此代码可以正常工作,但是当我在 AWS Lambda 上部署和运行它时,它会在提交表单之前结束。 I tried to remove the Promise and run the code inside it but got the same result!我试图删除 Promise 并运行其中的代码,但得到了相同的结果!

I don't know if it starts the submission or not, but the last thing I see on the cloud logs is Uploading... , and the invocation ends after it immediately.我不知道它是否开始提交,但我在云日志上看到的最后一件事是Uploading... ,然后调用立即结束。

How to make the Lamda function waits until the promise is resolved?如何让Lamda function等到promise解决?

This is missing a return statement as mentioned by Mark in the comments:这缺少 Mark 在评论中提到的return声明:

import request from 'request';
import FormData from 'form-data';

export const handler = async (event, context) => {
  // --- here, promises work with return values
  return new Promise((resolve, reject) => {
   // ... rest of your code
  });
};

But can be simplified extensively (assuming modern Node.js) without any nesting:但是可以在没有任何嵌套的情况下进行广泛的简化(假设是现代的 Node.js):

import request from 'request';
import FormData from 'form-data';
import { promisify } from 'util';

export const handler = async (event, context) => {
    const form = new FormData();
    console.log('Streaming ...');
    form.append('file', request('https://cdn.mysite.com/video.mp4'));
    console.log('Uploading ...');
    // Invocation ends here!
    await promisify(cb => form.submit('https://www.someapi.com/upload', cb))()
    const bodyParts = await response.toArray();
    return response.map(x => x.toString()).join('');
};

In general you almost never need to wrap things in new Promise in code.一般来说,您几乎不需要在代码中将东西包装在new Promise中。

I was able to resolve this by using a non-async handler , and removing the promise from the code.我能够通过使用非异步处理程序并从代码中删除 promise 来解决此问题。 Here's a working copy of my code:这是我的代码的工作副本:

import request from 'request';
import FormData from 'form-data';

export const handler = (event, context, callback) => {
  const form = new FormData();
  console.log('Streaming ...');
  form.append('file', request('https://cdn.mysite.com/video.mp4'));
  console.log('Uploading ...');
  form.submit( 'https://www.someapi.com/upload', (error, response) => {
    if (error) throw error;
    let body = '';
    response.on('data', chunk => {
      body += chunk.toString();
    });
    response.on('end', () => {
      console.log('Done ...');
      callback(null, JSON.parse(body));
    });
    response.resume();
  });
};

In this case, the Lambda function will wait for the callback to terminate, based on the AWS Lambda function handler in Node.js documentation. In this case, the Lambda function will wait for the callback to terminate, based on the AWS Lambda function handler in Node.js documentation.

I believe this has something to do with the default timeout value of Lambda.我相信这与 Lambda 的默认超时值有关。

By default, Lambda stops executing a function after 3 seconds.默认情况下,Lambda 在 3 秒后停止执行 function。

If your code needs to run longer, you can modify the timeout settings in General Configuration of a specific Lambda function:如果您的代码需要运行更长时间,您可以在特定 Lambda function 的常规配置中修改超时设置:
[+] https://docs.aws.amazon.com/lambda/latest/dg/configuration-function-common.html#configuration-common-summary [+] https://docs.aws.amazon.com/lambda/latest/dg/configuration-function-common.html#configuration-common-summary

The maximum timeout value is 15 minutes as of 15-09-2022.截至 2022 年 9 月 15 日,最大超时值为 15 分钟。

I recommend you try increasing this value.我建议您尝试增加此值。

Hope this helps!!希望这可以帮助!!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM