Lambda에서 비동기 코드를 사용하는 방법을 이해할 수 없습니다. 결과는 당혹 스럽습니다. 두 가지 기능을 만들어 보겠습니다.
const sendToFirehoseAsync = async (param) => {
console.log(param);
const promise = new Promise(function(resolve, reject) {
var params = {
DeliveryStreamName: 'TestStream',
Records: [{ Data: 'test data' }]
};
console.log('params', params);
firehose.putRecordBatch(params, function (err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log('Firehose Successful', data); // successful response
});
});
return promise;
}
과
const sendToFirehoseSync = (param) => {
console.log(param);
var params = {
DeliveryStreamName: 'TestStream',
Records: [{ Data: 'test data' }]
};
console.log('params', params);
firehose.putRecordBatch(params, function (err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log('Firehose Successful', data); // successful response
});
}
이제 그들을 실행하고 무슨 일이 일어나는지 봅시다!
비동기 기능 실행-잘 작동합니다.
exports.handler = async (event) => {
let res = await sendToFirehoseAsync('test1');
return res;
}
2020-11-05T20:19:16.146+13:00 START RequestId: e4c505ea-1717-4998-ad0d-a42434f0a0c1 Version: $LATEST
2020-11-05T20:19:16.148+13:00 2020-11-05T07:19:16.147Z e4c505ea-1717-4998-ad0d-a42434f0a0c1 INFO test1
2020-11-05T20:19:16.149+13:00 2020-11-05T07:19:16.149Z e4c505ea-1717-4998-ad0d-a42434f0a0c1 INFO params { DeliveryStreamName: 'TestStream', Records: [ { Data: 'test data' } ] }
2020-11-05T07:19:16.245Z e4c505ea-1717-4998-ad0d-a42434f0a0c1 INFO Firehose Successful {
FailedPutCount: 0,
Encrypted: false,
....
그러나 await를 사용하여 함수를 두 번 호출하면 (아래 참조) 정확히 동일한 응답을받습니다 (예 : 테스트 2에 대한 console.log가 표시되지 않음 등). 두 번째 호출이 발생하지 않는 것과 같습니다. 무슨 일입니까? await
첫 번째 함수가 해결 될 때까지 실행을 중단 한 다음 계속할 것이라고 가정했습니다 .
let res = await sendToFirehoseAsync('test1');
res = await sendToFirehoseAsync('test2');
return res;
이제 몇 번 더 연속해서 실행 해 보겠습니다.
console.log('async call 1');
await sendToFirehoseAsync('test1');
console.log('async call 2');
await sendToFirehoseAsync('test2');
console.log('sync call 1');
let resp1 = await sendToFirehoseSync('1');
console.log('sync call 2');
let resp2 = await sendToFirehoseSync('2');
console.log('after sync calls');
2020-11-05T20:35:28.465+13:00 2020-11-05T07:35:28.464Z 5a9e551f-ecc6-4f18-8af4-a11b1b29d835 INFO async call 1
2020-11-05T20:35:28.465+13:00 2020-11-05T07:35:28.465Z 5a9e551f-ecc6-4f18-8af4-a11b1b29d835 INFO test1
2020-11-05T20:35:28.467+13:00 2020-11-05T07:35:28.467Z 5a9e551f-ecc6-4f18-8af4-a11b1b29d835 INFO params { DeliveryStreamName: 'TestStream', Records: [ { Data: 'test data' } ] }
2020-11-05T20:35:28.577+13:00 2020-11-05T07:35:28.577Z 5a9e551f-ecc6-4f18-8af4-a11b1b29d835 INFO Firehose Successful { FailedPutCount: 0, Encrypted: false, RequestResponses: [ { RecordId: '4v+6H3T3koBggYYvdu/U6fg4h0C8m4taPVYznfYT4fIAWmm9XKu4/9F9jEgjdZFE02IsNgYs0/ORGzz1l2udEzCJUN1dRR1YCHSi/jiLI/DHGpTkoyN89VUG0jGzNlAERgUNCIwxXlCYww/l2HSGjK8++f+qmRj7sTCY/J4/QlV2sqhcXSlJjKhkK+A+Ib7w2+WwdZ5gliF64fSP9qkQSpeSutOh68o6' } ] }
2020-11-05T20:35:28.580+13:00 END RequestId: 5a9e551f-ecc6-4f18-8af4-a11b1b29d835
다시 한 번 결과가 하나만 반환됩니다. 나머지는 없어?!
그리고 두 번의 비동기 호출로 동일한 결과를 얻은 다음 두 번의 동기화 호출과 좋은 측정을 위해 하나 더 호출합니다.
console.log('async call 1');
await sendToFirehoseAsync('test1');
console.log('async call 2');
await sendToFirehoseAsync('test2');
console.log('sync call 1');
let resp1 = await sendToFirehoseSync('1');
console.log('sync call 2');
let resp2 = await sendToFirehoseSync('2');
console.log('after sync calls');
const promise = new Promise(function(resolve, reject) {
var params = {
DeliveryStreamName: 'TestStream',
Records: [{ Data: 'test data 2' }]
};
console.log('params', params);
firehose.putRecordBatch(params, function (err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log('Firehose Successful', data); // successful response
});
});
return promise;
그러나 ... 마지막 예제를 다시 실행하고 2 개의 비동기 호출을 주석 처리하면 다른 결과가 나타납니다.
console.log('sync call 1');
let resp1 = await sendToFirehoseSync('1');
console.log('sync call 2');
let resp2 = await sendToFirehoseSync('2');
console.log('after sync calls');
const promise = new Promise(function(resolve, reject) {
var params = {
DeliveryStreamName: 'TestStream',
Records: [{ Data: 'test data 2' }]
};
console.log('params', params);
firehose.putRecordBatch(params, function (err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log('Firehose Successful', data); // successful response
});
});
return promise;
2020-11-05T20:42:08.713+13:00
2020-11-05T07:42:08.713Z 333feae9-f306-409c-89c8-1707e0547ba3 INFO sync call 1
2020-11-05T07:42:08.713Z 333feae9-f306-409c-89c8-1707e0547ba3 INFO sync call 1
2020-11-05T20:42:08.713+13:00 2020-11-05T07:42:08.713Z 333feae9-f306-409c-89c8-1707e0547ba3 INFO 1
2020-11-05T20:42:08.715+13:00 2020-11-05T07:42:08.715Z 333feae9-f306-409c-89c8-1707e0547ba3 INFO params { DeliveryStreamName: 'TestStream', Records: [ { Data: 'test data' } ] }
2020-11-05T20:42:08.760+13:00 2020-11-05T07:42:08.760Z 333feae9-f306-409c-89c8-1707e0547ba3 INFO after sync calls
2020-11-05T20:42:08.760+13:00 2020-11-05T07:42:08.760Z 333feae9-f306-409c-89c8-1707e0547ba3 INFO params { DeliveryStreamName: 'TestStream', Records: [ { Data: 'test data 2' } ] }
2020-11-05T20:42:08.808+13:00 2020-11-05T07:42:08.807Z 333feae9-f306-409c-89c8-1707e0547ba3 INFO Firehose Successful { FailedPutCount: 0, Encrypted: false, RequestResponses: [ { RecordId: 'iWeCDK6kukfkLfh/1mg791g3sIVpDC1hNNokJuTGFJJaLBNd1TvvCiWHV4z2iiWS3hOvu9OmKVnUofCPbr5uewKPAQBdiCJp9iVIzTakcL5bb4CkyOZKxzLX4NOxTP94Z0j64KgssWo10z7jEhDoevF8NTMZR+tUlhHmYtEGcQq2YViwwXhpYX8MP4yvS5xSRo+sjJXEcyoty+Pvt1UFWGelEKIygtnO' } ] }
2020-11-05T20:42:08.865+13:00 2020-11-05T07:42:08.865Z 333feae9-f306-409c-89c8-1707e0547ba3 INFO Firehose Successful { FailedPutCount: 0, Encrypted: false, RequestResponses: [ { RecordId: 's5loZTT8d4J0fhSjnJli0LzOzljnvgvC99AvdSeqkj/j9xp5RnjstL5UxQXm5t+uyEbSSe21XZxwaUU/D7XVsCzpJ6F5nlnzsOZBLd6vyaF3bc2lSUo2DM2u9dGetJPMahC1b0rO+GXod91sC9XumS8QWIVePcww2DH0IM46RuoLEVVR3/kgcnvhIm/UU67JuvZkFTCAP/jss0VwVUY2vmzfdvw4mJT4' } ] }
2020-11-05T20:42:08.867+13:00 END RequestId: 333feae9-f306-409c-89c8-1707e0547ba3
내가 볼 수있는 유일한 패턴은 수익입니다. 비동기 함수에는 반환이 있습니다. 이로 인해 함수뿐만 아니라 전체 람다가 반환 될 수 있습니까? 이 (안타깝게도) 긴 실험이 도움이되고 누군가 이것이 어떻게 작동하는지 알려줄 수 있기를 바랍니다. 건배.
** 해결 및 거부 추가 **
console.log('before');
await sendToFirehosePromise('thing');
console.log('after');
....
async function sendToFirehosePromise(record) {
var params = {
DeliveryStreamName: 'TestStream',
Records: [{ Data: 'test data' }]
};
const promise = new Promise((resolve, reject) => {
firehose.putRecordBatch(params, (err, data) => {
if (err) return reject(err);
return resolve(data);
});
});
return promise;
}
람다에서 순수한 비동기 호출을 가능한 많이 줄여 보겠습니다.
function f(p) {
console.log(p);
return new Promise(res => res('result ' + p));
}
exports.handler = async () => {
let res = await f(1);
console.log(res);
res = await f(2);
console.log(res);
res = await f(3);
console.log(res);
}
인쇄물:
2020-11-05T10:40:25.298Z bd564d91-480f-4dcd-8134-1481fa59a946 INFO 1
2020-11-05T10:40:25.298Z bd564d91-480f-4dcd-8134-1481fa59a946 INFO result 1
2020-11-05T10:40:25.298Z bd564d91-480f-4dcd-8134-1481fa59a946 INFO 2
2020-11-05T10:40:25.298Z bd564d91-480f-4dcd-8134-1481fa59a946 INFO result 2
2020-11-05T10:40:25.298Z bd564d91-480f-4dcd-8134-1481fa59a946 INFO 3
2020-11-05T10:40:25.299Z bd564d91-480f-4dcd-8134-1481fa59a946 INFO result 3
이제 당신의 것을 비교하십시오. 첫째,이 서명이 잘못되었습니다 (또는 최소한 불필요합니다) const sendToFirehoseAsync = async (param)
. 비동기는 무언가를 기다리는 경우에만 필요합니다. 기다리지 않고 기다리지 않는 경우 비동기로 표시 할 필요가 없습니다. 비동기 함수는 promise를 반환하는 모든 것을 기다릴 수 있습니다. 함수가 promise를 반환하고 아무것도 기다리지 않으면 비동기로 표시하지 마십시오.
이제 불필요하게 약속과 비동기를 혼합하는 부분입니다.
async function sendToFirehosePromise(record) {
var params = {
DeliveryStreamName: 'TestStream',
Records: [{ Data: 'test data' }]
};
const promise = new Promise((resolve, reject) => {
firehose.putRecordBatch(params, (err, data) => {
if (err) return reject(err);
return resolve(data);
});
});
return promise;
}
async를 사용하려는 경우 async를 사용하십시오. 모든 AWS SDK 호출은 AWS.Request
. 이 유형에는 promise()
메소드 가 포함되어 있습니다 . 실제 약속 표기법을 사용하는 대신 해당 약속을 기다릴 수 있습니다.
async function sendToFirehosePromise(record) {
var params = {
DeliveryStreamName: 'TestStream',
Records: [{ Data: 'test data' }]
};
return await firehose.putRecordBatch(params).promise();
}
이는 SDK를 사용자 지정 약속으로 묶는 대신 async / await를 적절하게 사용하는 것입니다. 이제 핸들러에서 원하는만큼 함수를 기다릴 수 있으며 항상 작동합니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다