Я пытаюсь создать JS-функцию, которая считывает файл из хранилища, записывает его содержимое в базу данных и выталкивает сообщение результата в очередь. Чтение и обработка db в порядке, но ничего не происходит при записи в очередь.
Код выглядит так:
process(file)
.then(() => {
context.bindings.outQueue = { file };
return context.log('File processing completed successfully');
})
.catch(err => context.log.error(err));
Если я использую context.done() вместо этого, я получаю следующую ошибку:
Error: Choose either to return a promise or call 'done'. Do not use both in your script.
В любом случае в очередь не записывается сообщение. Что не так?
Есть несколько вещей, которые, скорее всего, вызывают проблемы. Во-первых, вы должны вернуться в основную область функции. Невозвращение приведет к зависанию приложения-функции, что, вероятно, связано с тем, что вы пытались добавить context.done(). Во-вторых, вы не должны вызывать context.done(), когда он может вернуться преждевременно. Сообщение об ошибке, которое вы видели, пытается помешать вам сделать это. В-третьих, вы должны возвращать свое обещанное обещание вместо вызова context.done() '. Это позволит вам правильно писать в очередь.
К первому вопросу: я думаю, вы предполагаете, что возвращаетесь внутрь .then(() => {... });
возвращается для функции с большим охватом. Помните, что функция лямбда, переданная в метод.then(), просто возвращает значение выполнения, которое используется для того, чтобы передать результат одного обещания другому обещанию (docs здесь). Как побочная заметка, я предлагаю не возвращать context.log('File processing completed successfully');
(просто назовите его, не возвращайте), так как это то же самое, что и возвращение void, но приводит к более запутанному коду.
Во второй момент: вызов context.done() внутри .then(() => {... });
вызывает метод, указывающий, что основная функция от асинхронной функции fork'd. Это опасно, потому что теоретически, в любой момент после .then(() => {... });
определяется, основной код функции может быть убит этим вызовом context.done().
К третьему вопросу: если вы просто вызываете context.done() в область основной функции вместо того, чтобы возвращать обещание, у вас будет противоположная проблема с точкой №2 (основной код выйдет и остановит выполнение fork ' d асинхронная задача до завершения асинхронного кода).
Вот пример простой функции JS, которая ждет обещания и записывает в очередь:
Пример:
module.exports = function (context, req) {
context.log("Starting function");
// Mock Promise
let doWork = new Promise(
(resolve, reject) => {
setTimeout(resolve, 100, 'foo');
console.log("Work in promise");
}
);
doWork.then(() => {
context.log("Work AFTER promise");
context.bindings.queue1= "Queue message";
context.log("Message queued!");
}).catch(err => context.log.error(err));
// This is the correct scope to return promise
return doWork;
};
context.done()
если вы не вернете обещание? Вы называетеcontext.done
после назначения вывода?