试图理解Lambda中的async/await

0

【以下的问题经过翻译处理】 在这里得到了一些很好的帮助,我已经在理解我尝试解决的问题方面取得了一些进展,但我仍然缺少一些基本的东西。

我的用例是一个现有的基于Lambda的规则引擎,使用Node编写。一组规则通常使用来自先前规则评估的结果,因此按顺序同步执行它们是最合理的。我可以看到如何可能为所有内容启动单独的异步函数调用,然后在之后某种方式清理掉混乱,可能会重新调用由于缺少数据而失败的那些函数,但这将是一场噩梦。

因此,我正在尝试在目前完全同步的体系结构中插入一个异步调用,我甚至不确定在JS/Node中是否可能。非常感谢任何建议!这可能是一个JavaScript甚至是一个Node.js问题,而不是一个AWS Lambda问题,但根据我的研究,异步函数的调度方式似乎对这种组合是独特的,所以我想从这里开始!

不过,如果能搞清楚这个问题,那就太好了...我会感觉自己不那么愚蠢 :)

下面是一个简化的示例,展示了我想要实现的内容,即在ChatGPT中插入一个异步调用:

const { Configuration, OpenAIApi } = require("openai");

exports.handler = async function(event, context, callback) {

    var output;

	try {
		output = await makeSentence(event.prompt);
		console.log('output: ' + output);
	}
	catch (e){
		output = e.message;
	}

	let response = {
		statusCode: 200,
		headers: { "Content-type" : "application/json" },
		body: JSON.stringify(output)
	};

	return response;
};

async function makeSentence(prompt)
{
	const rule1 = getOpening();                     // existing sync call
	const rule2 = await getMiddle(prompt);          // new async call
	const rule3 = getClosing(rule1 + ' ' + rule2);  // existing sync call
	
        // assemble all the results and return the final result
	return rule3;
}

function getOpening()
{
	const greeting = [ 'Hello', 'Hi', 'Greetings'];
	const random = Math.floor(Math.random() * greeting.length);
	
	return '<sentence>' + greeting[random];
}

async function getMiddle(prompt)
{
    console.log("getMiddle('" + prompt + "')");
    
	const configuration = new Configuration({
		apiKey: "my-api-key-here",
	});
	const openai = new OpenAIApi(configuration);

	await openai.createCompletion({
			model: "text-davinci-003",
			prompt: prompt,
			temperature: 0.7,
			max_tokens: 500,
			top_p: 1,
			frequency_penalty: 0,
			presence_penalty: 0,
	}).then(res => {
        var text = res.data.choices[0].text;
        console.log('got response: ' + text);
        return text;
    }).catch(error => {
        console.log('Error: ' + error.message);
        return error.message;
    });
}

function getClosing(resp)
{
	return resp + '</sentence>';
}

这个示例的结果是: Event JSON

{
  "prompt": "what did the fox say?"
}

Response

{
  "statusCode": 200,
  "headers": {
    "Content-type": "application/json"
  },
  "body": "\"<sentence>Greetings undefined</sentence>\""
}

Function Logs

START RequestId: c7153471-1563-430d-889a-cb394737b5dd Version: $LATEST
2023-04-26T17:16:44.120Z	c7153471-1563-430d-889a-cb394737b5dd	INFO	getMiddle('what did the fox say?')
2023-04-26T17:16:46.119Z	c7153471-1563-430d-889a-cb394737b5dd	INFO	got response: 

The fox usually says, "Ring-ding-ding-ding-dingeringeding!"
2023-04-26T17:16:46.119Z	c7153471-1563-430d-889a-cb394737b5dd	INFO	getClosing("<sentence>Hi undefined")
2023-04-26T17:16:46.119Z	c7153471-1563-430d-889a-cb394737b5dd	INFO	output: <sentence>Hi undefined</sentence>
END RequestId: c7153471-1563-430d-889a-cb394737b5dd
REPORT RequestId: c7153471-1563-430d-889a-cb394737b5dd	Duration: 2039.43 ms	Billed Duration: 2040 ms	Memory Size: 128 MB	Max Memory Used: 77 MB

Topics
Serverless
Compute
Tags
Serverless
AWS Lambda
Language
English
dmb0058
asked 5 months ago241 views
profile picture
专家
已提问 5 个月前9 查看次数
1 回答
0

【以下的回答经过翻译处理】 我找到了答案...

如果对任何人有帮助,下面的代码在顺序中混合了同步和异步函数调用,在等待异步函数完成后继续到下一个函数。

const { Configuration, OpenAIApi } = require("openai");

exports.handler = async function(event, context, callback) {

    var output;

    try {
	const rule1 = getStart();                                    // call the first (sync) function

        const rule2 = await getMiddle(event.prompt).then(res => {    // call the second (async) function and wait
                return res.data.choices[0].text;
    	    }).catch(error => {
                return error.message;
            });
        
        output = getEnd(rule1 + ' ' + rule2);                        // call the third (sync) function
        console.log('result: ' + output);
    }
    catch (e){
	output = e.message;
    }

    let response = {
	statusCode: 200,
	headers: { "Content-type" : "application/json" },
        body: JSON.stringify(output)
    };

    return response;
};

function getStart()
{
    return '<sentence>Hi there,';
}

async function getMiddle(prompt)
{
    console.log("getMiddle('" + prompt + "')");

    const configuration = new Configuration({
        apiKey: "my-api-key-here",
    });
    const openai = new OpenAIApi(configuration);

    return openai.createCompletion({
            model: "text-davinci-003",
            prompt: prompt,
            temperature: 0.7,
            max_tokens: 500,
            top_p: 1,
            frequency_penalty: 0,
            presence_penalty: 0,
    });
}

function getEnd(resp)
{
    return resp + '</sentence>';
}

Response

{
  "statusCode": 200,
  "headers": {
    "Content-type": "application/json"
  },
  "body": "\"<sentence>Hi there, \\n\\nThe fox usually makes a sound similar to \\\"Skrr! Skrr!\\\"</sentence>\""
}

Function Logs

START RequestId: 41cc46f8-9a9b-4500-854e-574739511e2e Version: $LATEST
2023-04-27T10:55:22.820Z	41cc46f8-9a9b-4500-854e-574739511e2e	INFO	getMiddle('what did the fox say?')
2023-04-27T10:55:25.040Z	41cc46f8-9a9b-4500-854e-574739511e2e	INFO	result: <sentence>Hi there, 

The fox usually makes a sound similar to "Skrr! Skrr!"</sentence>
END RequestId: 41cc46f8-9a9b-4500-854e-574739511e2e
profile picture
专家
已回答 5 个月前

您未登录。 登录 发布回答。

一个好的回答可以清楚地解答问题和提供建设性反馈,并能促进提问者的职业发展。

回答问题的准则