Переменная не определена вне области действия функции, несмотря на то, что она назначена? - PullRequest
0 голосов
/ 03 марта 2019

Проблема

У меня проблема с приложением MERM, из-за которого переменная, объявленная в теле всей функции, назначается в подфункции, однако всякий раз, когдаЯ пытаюсь манипулировать / отображать эту переменную только в конце всей функции, она возвращает «неопределенное».

Код

getSimilarCasesFromID: function(req, res, next) {
    let queryString = "id::"+req.params.id; 
    let params = {
        'query': queryString,
        'environment_id':environmentId,
        'collection_id': collectionId,
        'configuration_id': configurationId,
        return: 'enriched_text'
    }

    let filterStrArr = [];
    const FILTER_CONCEPT = "enriched_text.concepts.text:";
    let filterStr ="";

    discovery.query(params, (error, results) => {
        if (error) {
            next(false, err, []);
        } else {
            let conceptSize = results.results[0].enriched_text.concepts.length;
            let concepts = {};
            for (let i = 0; i < conceptSize; i++) {
                concepts[i] = { 
                    text: results.results[0].enriched_text.concepts[i].text,
                    relevance: results.results[0].enriched_text.concepts[i].relevance
                 };

                filterStrArr[i] = FILTER_CONCEPT + concepts[i].text;
            }

            filterStr = filterStrArr.join(",");
            console.log(filterStr);
            //1. Works and displays---------------
        }
    });

    console.log("FullString (2.)"+filterStr);
    //2. Undefined????????????????????------------

    next(true, [], []);
},

Я имею в виду строки (1.) и (2.).Я не могу сказать, пропустил ли я что-то и допустил глупую, мелкую ошибку.

Вывод на сервер: enter image description here

Интересно,как вы видите на рисунке 1, FullString (2.) появляется перед строкой (1.).Может ли это быть из-за времени отклика от Watson Discovery?Учитывая, что сервис находится в Сиднее, Австралия?И если да, кто-нибудь еще имел опыт с этим?

Ответы [ 2 ]

0 голосов
/ 03 марта 2019

discovery.query является асинхронной функцией, поэтому переменная filterStr не будет определена, пока не будет достигнут обратный вызов.Вам нужно будет использовать filterStr в обратном вызове discovery.query или async/await в блоке try/catch, чтобы return results.

Асинхронные функции работали, позволяя емувыполняться без прерывания потока.Вот почему console.log(2.) исполняется, а спустя некоторое время console.log(1.) исполняется в рамках обратного вызова (из-за функции asynchronous требуется некоторое время для достижения обратного вызова).Вы пытаетесь что-то сделать synchronously, и для этого вам нужно провести рефакторинг своего кода. Нажмите здесь для получения дополнительной информации об асинхронном и синхронном выполнении.

Внутри обратного вызова :

getSimilarCasesFromID: function(req, res, next) {
  const queryString = "id::"+req.params.id; 
  const params = {
    'query': queryString,
    'environment_id':environmentId,
    'collection_id': collectionId,
    'configuration_id': configurationId,
    return: 'enriched_text'
  };

  const filterStrArr = [];

  const FILTER_CONCEPT = "enriched_text.concepts.text:";

  discovery.query(params, (error, results) => {
    if (error) {
      next(false, err, []);
    } else {
      let filterStr ="";

      const conceptSize = results.results[0].enriched_text.concepts.length;

      let concepts = {};
      for (let i = 0; i < conceptSize; i++) {
        concepts[i] = { 
          text: results.results[0].enriched_text.concepts[i].text,
          relevance: results.results[0].enriched_text.concepts[i].relevance
        };

        filterStrArr[i].push(FILTER_CONCEPT + concepts[i].text);
      }

      filterStr = filterStrArr.join(",");
      console.log(filterStr);

      // utilize filterStr here

      next(true, [], []);
    }
  });
},

С async/await:

getSimilarCasesFromID: async function(req, res, next) {
  const queryString = "id::"+req.params.id; 
  const params = {
    'query': queryString,
    'environment_id':environmentId,
    'collection_id': collectionId,
    'configuration_id': configurationId,
    return: 'enriched_text'
  }

  const filterStrArr = [];

  const FILTER_CONCEPT = "enriched_text.concepts.text:";

  let filterStr ="";

  try {
    const results = await discovery.query(params);

    const conceptSize = results.results[0].enriched_text.concepts.length;

    let concepts = {};
    for (let i = 0; i < conceptSize; i++) {
      concepts[i] = { 
        text: results.results[0].enriched_text.concepts[i].text,
        relevance: results.results[0].enriched_text.concepts[i].relevance
      };

      filterStrArr[i].push(FILTER_CONCEPT + concepts[i].text);
    }

    filterStr = filterStrArr.join(",");
    console.log(filterStr);

    // utilize filterStr here

    next(true, [], []);       

  } catch(err) {
     next(false, err, []);
  }
},
0 голосов
/ 03 марта 2019

discovery.query () принимает два свойства,
1 - параметр
2 - функция (также известная как обратный вызов)

Discover.query () выполняется, но возвращается до обратного вызовавыполняется,
next console.log ("FullString (2.)" + filterStr);выполняется
Наконец, выполняется обратный вызов.

Вам необходимо выполнить желаемые действия в обратном вызове.

Это боль, но так работает JavaScript.Точнее, как работает discovery.query ().Хуже того, когда у вас есть вложенные обратные вызовы, это может стать очень запутанным и иметь имя: «ад обратного вызова».Современные решения этой проблемы обещания и асинхронность ждут.

Удачи

...