尽管已分配变量,但未在函数范围之外定义变量?

时间:2019-03-03 17:17:49

标签: node.js reactjs express ibm-watson watson-discovery

问题

我在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 :(得分:1)

discovery.query()具有两个属性,
1-参数
2-函数(也称为回调)

discover.query()被执行,但在执行回调之前返回,
下一个console.log(“ FullString(2。)” + filterStr);被执行
最后,执行回调。

您需要在回调中执行所需的操作。

这很痛苦,但是JavaScript是这样工作的。更准确地说,discovery.query()是如何工作的。更糟糕的是,当您嵌套有回调时,它会变得非常混乱,并具有一个名称:“ callback hell”。解决这个问题的现代方法是承诺和异步。

祝你好运

答案 1 :(得分:1)

discovery.query是一个异步函数,因此变量filterStr在到达回调之前不会被定义。您需要在filterStr的回调中使用discovery.query或在async/await块中使用try/catchreturn results。 / p>

异步函数通过允许它在不中断线程的情况下执行来工作。因此,这就是为什么执行console.log(2.),然后稍后在回调中执行console.log(1.)的原因(由于函数为asynchronous,到达回调需要一些时间)。您正在尝试执行synchronously,并且需要重构代码。 Click here,以获取有关异步和同步执行的更多信息。

在回调之内

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, []);
  }
},