node.js Асинхронная привязка выходных данных хранилища Azure Queue

1

Я пытаюсь создать 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.

В любом случае в очередь не записывается сообщение. Что не так?

  • 0
    Так работает ли context.done() если вы не вернете обещание? Вы называете context.done после назначения вывода?
Теги:
azure-functions

1 ответ

1
Лучший ответ

Есть несколько вещей, которые, скорее всего, вызывают проблемы. Во-первых, вы должны вернуться в основную область функции. Невозвращение приведет к зависанию приложения-функции, что, вероятно, связано с тем, что вы пытались добавить 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;
};
  • 0
    Спасибо, это решает проблему

Ещё вопросы

Сообщество Overcoder
Наверх
Меню