Nano Hash - криптовалюты, майнинг, программирование

Асинхронная функция никогда не возвращается

Я использую Node версии 7.6.0, чтобы опробовать нативные функции async и await.

Я пытаюсь понять, почему мой асинхронный вызов, который просто зависает, никогда не разрешается.

Модуль НЛП:

const rest = require('unirest')
const Redis = require('ioredis')
const redis = new Redis()
const Promise = require('bluebird')
const nlp = {}
nlp.queryCache = function(text) {
    return new Promise(function(resolve, reject) {
        redis.get(text, (err, result) => {
            if (err) {
                console.log("Error querying Redis: ", err)
                reject(new Error("Error querying Redis: ", err))
            } else {
                if (result) {
                    let cache = JSON.parse(result)
                    console.log("Found cache in Redis: ", cache)
                    resolve(cache)
                } else {
                    resolve(null)
                }
            }
        })
    })
}

nlp.queryService = function(text) {
    console.log("Querying NLP Service...")
    return new Promise(function(resolve, reject) {
        rest.get('http://localhost:9119?q=' + text)
            .end((response) => {
                redis.set(text, JSON.stringify(text))
                resolve(response.body)
            })
    })
}

nlp.query = async function(text) {
    try {
        console.log("LET'S TRY REDIS FIRST")
        let cache = await nlp.queryCache(text)
        if (cache) {
            return cache
        } else {
            let result = await nlp.queryService(text)
            console.log("Done Querying NLP service: ", result)
            return result
        }
    } catch (e) {
        console.log("Problem querying: ", e)
    }

}
module.exports = nlp

Потребитель модуля:

const modeMenu = require('../ui/service_mode')
const nlp = require('../nlp')
const sess = require('../session')
const onGreetings = async function(req, res, next) {
    let state = sess.getState(req.from.id)
    if (state === 'GREET') {        
        let log = { 
            middleware: "onGreetings"           
        }
        console.log(log)
        let result = await nlp.query(req.text)
        console.log("XXXXXXXX: ", result)
        res.send({reply_id: req.from.id, message: msg})

    } else {
        console.log("This query is not not normal text from user, calling next()")
        next()
    }
};
module.exports = onGreetings;

Я не могу заставить код перейти к следующей строке:

console.log("XXXXXXXX: ", result) 

Я вижу, что запрос был выполнен успешно в модуле НЛП

Вывод журнала консоли

Изменить: добавлен оператор console.log в тело ответа

Консольный вывод для фактического response.body

Выписка журнала


  • Вы пытались поместить асинхронность во все функции, которые вы пытаетесь дождаться? Так что попробуйте добавить await перед новым промисом. 23.02.2017
  • @Gilsdav - вы не return await new Promise - async/await - это синтаксический сахар для промисов 23.02.2017
  • какие из остальных console.log сообщений отображаются? Ваша логика кажется здравой 23.02.2017
  • Эй, ребята, спасибо, что посмотрели это. Как видите, @JaromandaX. Я пытаюсь запросить службу NLP только после того, как не могу найти ее в Redis. Вывод вызова nlp.query() указывает на то, что вызов успешно завершился, но никогда не передает его в переменную результата. 23.02.2017
  • поместите console.log(response.body) внутри .end((response) => { ... } - что это показывает 23.02.2017
  • Я обновил еще пару выходных результатов 23.02.2017
  • Если вы только что не столкнулись с ошибкой, какая-то часть информации должна отсутствовать. Единственное, что я могу предложить, это запустить ваше приложение с помощью node --inspect, установить точку останова в вашем промежуточном программном обеспечении и пройти через поток выполнения после его запуска (не забудьте проверить параметр Async в отладчике Chrome). 23.02.2017
  • Похоже, вы не обрабатываете какие-либо ошибки из rest.get, и в этом случае обещание останется неразрешенным (и повесит ваш async function) на неопределенный срок. 23.02.2017

Ответы:


1

Наиболее вероятной причиной является ошибка в промисе, которую вы не отлавливаете. Я считаю, что это помогает избежать try-catch во всех методах, кроме самого вызывающего, и если метод может быть await-ed, это почти всегда должно быть.

В вашем случае я думаю, что проблема здесь:

nlp.queryService = function(text) {
    console.log("Querying NLP Service...")
    return new Promise(function(resolve, reject) {
        rest.get('http://localhost:9119?q=' + text)
            .end((response) => {
                redis.set(text, JSON.stringify(text)) // this line is fire and forget
                resolve(response.body)
            })
    })
}

В частности, эта строка: redis.set(text, JSON.stringify(text)) - эта строка вызывает функцию, и ничто не улавливает никаких ошибок.

Исправление состоит в том, чтобы обернуть все ваши методы Redis в промисы, а затем всегда await их:

nlp.setCache = function(key, value) {
    return new Promise(function(resolve, reject) {
        redis.set(key, value, (err, result) => {
            if (err) {
                reject(new Error("Error saving to Redis: ", err));
            } else {
                resolve(result);
            }
        });
    })
}

nlp.queryService = async function(text) {
    console.log("Querying NLP Service...")
    const p = new Promise(function(resolve, reject) {
        rest.get('http://localhost:9119?q=' + text)
            .end((response) => { resolve(response.body) });

        // This is missing error handling - it should reject(new Error... 
        // for any connection errors or any non-20x response status 
    });

    const result = await p;

    // Now any issue saving to Redis will be passed to any try-catch
    await nlp.setCache(text, result);
    return;
}

Как правило, я считаю, что лучше всего:

  • Держите явные промисы на низком уровне — используйте Promise функции-оболочки для ваших rest и redis обратных вызовов.
  • Убедитесь, что ваши обещания reject с new Error, когда что-то пойдет не так. Если Promise не resolve и не reject, тогда ваш код на этом останавливается.
  • Каждый вызов одной из этих оберток промисов должен иметь await
  • try-catch прямо вверху - пока каждый Promise имеет await номер, любая ошибка, выданная любым из них, попадет на верхний уровень catch

Большинство проблем будут либо:

  • У вас есть Promise, который может не дать resolve или reject.
  • Вы называете async function или Promise без await.
24.02.2017
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

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

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..