3

Я хочу создать функцию, которая вызывает API (стороннюю сторону) и сразу же возвращается, но ожидает ответа API.Функция Lambda не возвращается, пока не завершится запрос async

Вот пример кода:

var request = require('request'); 

// When I call functionOne it should trigger functionTwo and should end immediately, 
// but unfortunately, it is waiting for functionTwo to end 
module.exports.functionOne = (event, context, cb) => { 
    const uri = 'https://xxxxxxxxx.execute-api.us-east-1.amazonaws.com/dev/functionTwo'; 
    request.post({ uri: uri }); 
    cb(null, "done functionOne"); 
}; 

module.exports.functionTwo = (event, context, cb) => { 
    console.log("i'm functionTwo"); 
    setTimeout(function() { 
     console.log("I'm functionTwo about to end"); 
     context.succeed("done functionTwo"); 
    }, 5000); 
}; 

Кроме того, если я пытаюсь вызвать context.succeed() вместо cb(), даже предотвратить вызов API и возврата функции сразу без вызова API.

Я также создал проблему на GitHub.

Дополнительная информация:

  • Serverless Framework: v1.0.0-
  • РК-2
  • Узел: v6.9.1
  • ОС: Win 10

ответ

2

Извините, но вы можете 't достичь того, чего вы хотите, по крайней мере, не таким образом.

При вызове другой функции с помощью request.post(), вы должны обеспечить обратный вызов, и вы должны ждать его, чтобы закончить.

Что вы можете сделать, это позвонить request.abort(), но это взломанное решение.

module.exports.functionOne = (event, context, cb) => { 
    const uri = 'https://xxxxxxxxx.execute-api.us-east-1.amazonaws.com/dev/functionTwo'; 
    const r = request.post({ uri: uri }, (error, response, body) => { 
     cb(error, "done functionOne"); 
    }); 

    r.abort(); 
    cb(null, 'forced abort on functionOne'); 
}; 

Почему этот хак? Потому что вы не можете отменить немедленно. Вам нужно подождать несколько миллисекунд, чтобы запрос был получен на другом сервере, но точно не знать, когда это произойдет.

Если вы знаете, что вторая Лямбда будет работать в течение 2 минут, вы можете добавить функцию setTimeout, чтобы прервать запрос через 5 секунд и избежать длительной работы functionOne в режиме ожидания. Но опять же, это плохое решение.

Почему вы не размещаете код functionTwo внутри functionOne, чтобы избежать запуска второй лямбда?

Другим обходным решением было бы вызвать тему SNS от functionOne и настроить эту тему для запуска functionTwo.

+0

FunctionTwo здесь, например, на самом деле есть api, который является третьим лицом, и я отправляю почтовый запрос на этот api с некоторыми данными, и на самом деле это slack api –

+0

Хорошо, поэтому я предлагаю вам создайте другой вопрос, специфичный для API Slack. Если это была другая функция лямбда, вы можете использовать SNS, потому что она возвращается всего за несколько миллисекунд. Если Slack занимает несколько секунд, я не знаю, предоставляют ли они другой способ очереди запроса без необходимости ждать. – Zanon

+0

В противном случае вы можете прервать запрос, чтобы заставить Лямбду остановиться раньше, но, как я уже сказал, вам нужно подождать несколько минут, прежде чем Slack получит запрос. – Zanon