【问题标题】:Javascript: return a value to a variable outside of a callback function [duplicate]Javascript:将值返回给回调函数之外的变量[重复]
【发布时间】:2015-04-24 16:07:26
【问题描述】:

我有一个非常具体的问题,希望有人可以在这里帮帮我。当涉及到 NodeJS 时,我对 Javascript 更感兴趣。

我正在使用lodash_.forIn 功能来遍历并添加到数组内的对象中。整个事情看起来像这样:

[ 
  { id: 20,
    keywords: 'shirts'
  },
  { id: 18,
    keywords: 'shoes'
  } 
]

基本上它是保存在 db elasticsearch 中的关键字列表。我正在尝试找到一种方法,将这些关键字将返回的结果数量的计数器添加到此对象中。

此计数来自我们用来搜索产品数据库的 elasticsearch 设置。

我想得到的输出是这样的:

[ 
  { id: 20,
    keywords: 'shirts',
    count: 4
  },
  { id: 18,
    keywords: 'shoes',
    count: 15
  } 
]

这是我现在的代码:

function get_list( data ) {

  var list_data = data;
  var list = _.forIn( data, function( item, n, list_data ) {
    get_count( item, function( count_number ) {
      list_data[n].count = count_number;
    })
  });
  console.log( list, list_data );
}

function get_count( item, callback ) {

  var query = { // elasticsearch query here };  

  // elasticsearch query here, that returns the count in a callback
  es.count( query, function(count_number) { callback(count_number) } );
} 

当我运行它时,控制台将显示一个未更改的数组。我检查了每个函数的所有返回数据,一切都检查出来了。我似乎无法在listlist_data 上获得正确的数据。

附言。 这不是我的实际代码,但它几乎是它的要点,所以可能有一些拼写错误。

另外,listlist_data 是我试图弄清楚它是如何工作的结果。我已经尝试阅读 JS 回调如何工作,但我所看到的似乎都无法帮助我解决我的问题。

【问题讨论】:

  • 我已经看过这个问题,但那里的答案对我来说没有任何意义。我花了一整天的时间研究这些东西,其中大部分都超出了我的想象。这就是为什么我问了自己的问题,这使我更容易理解答案,因为它是针对我的问题的。现在没有人可以回答它,因为它被标记为重复。
  • 了解,但如果是这种情况,那么参考您已经看过的现有问题,然后就您仍然不了解的内容提出更具体的问题会很有帮助。就像现在一样,这确实是与被骗者完全相同的问题。
  • 我看不出这两个是完全相同的问题。我什至没有使用 jQuery(该页面上的答案似乎严重依赖的东西)。那么,我如何让这个问题与众不同?
  • 我不知道你为什么这么说,jQuery 只用在问答中的四个例子中。无论如何,请专门查看涉及 fs.readFile 的解决方案,因为它与您正在做的基本 node.js 异步查询概念相同。

标签: javascript node.js callback lodash


【解决方案1】:

只有在所有callbacks 都完成后才能检查list_data 对象。

如果您想验证您的get_count 函数是否正常工作,您可以将console.log 移到callback 中,这将导致控制台中有多个list_data 日志。

function get_list( data ) {

  var list_data = data;
  var list = _.forIn( data, function( item, n, list_data ) {
    get_count( item, function( count_number ) {
      list_data[n].count = count_number;
      console.log( list, list_data );
    })
  });

}

function get_count( item, callback ) {

  var query = { // elasticsearch query here };  

  // elasticsearch query here, that returns the count in a callback
  es.count( query, function(count_number) { callback(count_number) } );
} 

为了做到这一点,我建议使用 async 模块,它可以很好地处理像你这样的异步调用。

这是模块链接,您可以开始使用它:https://github.com/caolan/async

在我们的例子中,我将如何实现 async 模块:

var async = require('async');

function get_list(data) {

    var list_data = data;
    //Transform all the list_data objects adding the count prop.
    async.map(list_data, get_count, function(err, results) {
        console.log(results);
    });
}

function get_count(item, callback) {
    var query = { // elasticsearch query here 
    };
    // elasticsearch query here, that returns the count in a callback
    es.count(query, function(count_number) {
        //add the new prop to the item
        item.count = count_number;
        //return the transformed object
        callback(null, item);
    });
}

【讨论】:

  • 我不想验证get_count 函数中的listlist_data 变量。我已经这样做了。我想知道的是如何在数组之外获得正确的结果,将数据作为结果返回到 API 路由。
  • 顺便说一下,我正在使用 locomotivejs 作为 MVC 框架,如果有帮助的话。它建立在 express 框架之上。
  • 你好,无能!为此,我将实施async.queue 您需要帮助吗? github.com/caolan/async#queue
  • 是的,考。我不完全理解 javascript 回调是如何工作的(我主要是 javascript 和编程新手)。我已阅读该链接上的文档,但似乎无法理解如何将其应用于我的问题。
  • 嘿@Clueless 刚刚包含了一个使用.map 函数的示例代码,我修改了get_count 函数来转换对象而不是只返回计数。检查这是否适合您 =)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-04
  • 1970-01-01
  • 2016-10-16
  • 2014-10-06
  • 2021-12-29
  • 1970-01-01
相关资源
最近更新 更多