【问题标题】:Nodejs module function returns undefined, not asynchronousNodejs模块函数返回未定义的,不是异步的
【发布时间】:2015-03-27 12:08:35
【问题描述】:

对 Node 来说非常(非常)新,所以这可能很愚蠢。我有一个模块,它定义了我迭代的各种路由以定义应用程序的路由。这工作正常。

在设置路线时,我想在另一个模块 language 中调用一个函数 checkAvailableTranslation 来检查该页面的翻译是否存在于另一种语言中(req.locale 是我们正在尝试查找的用户喜欢的语言匹配),如果是,则返回它的 URL 片段。

strings 对象是从 json 文件加载的,其中包含一个项目 translations,它是映射到 URL 片段的 ISO 国家/地区代码数组。

** app.js **

var routes = require("./config/routing.js")
routes.forEach(function(item) {
    item.routes.forEach(function(route) {
        app.get(route.path, function(req, res) {
            var strings = require(route.strings)
            translations = language.checkAvailableTranslation(req.locale, strings.translations))
            console.log(translations) // undefined?!?!?!?!
            res.render(route.render, {
                layout: route.layout,
                strings: strings
            })
        })
    })
})

** strings.translations **

[
    { "fr": "/fr" },
    { "ar": "/ar" },
    { "es": "/es" },
    { "pt": "/pt" },
    { "de": "/de" }
]

** 语言.js **

module.exports = function() {
    var module = {}

    module.checkAvailableTranslation = function(language, translations) {
        translations.forEach(function(el) {
            if( el[language] ) {
                console.log(el[language]) // this logs a matched language
                return el[language] // this disappears into the ether
            }
        })
    }
    return module
}

因此,translations.forEach 成功迭代并找到匹配项时,一切通常都按预期运行。但是,它似乎没有将值返回给 app.js - 当我输出函数的返回值时,我得到undefined

strings 是从 json 文件加载的事实是否使它成为一个异步调用,就好像它是一个数据库一样?如果是这样(这需要解释),我应该在这里做什么来建立处理这个问题的承诺?

【问题讨论】:

    标签: javascript json node.js express


    【解决方案1】:

    您正在从 forEach 回调返回,这是不可能的。 您需要手动遍历数组或将结果写入您的 checkAvailableTranslation 方法范围内的变量中(但仍要遍历 translations 中的所有项)。

    手动“forEach”

    module.checkAvailableTranslation = function(language, translations) {
        for (
            var i = 0, translation = translations[i][language];
            i < translations.length;
            i++, translation = translations[i][language]
        ) {
            if (translation)
                return translation;
        }
    }
    

    或使用Array.prototype.some

    function (language, translations) {
        var res;
        translations.some(function (translation) {
            return !!(res = translation[language]);
        });
        return res;
    }
    

    编辑:忍者方法

    function n(l,t,i){return t[i|0][l]||g(l,t,(i|0)+1)}
    

    【讨论】:

    • 哦,对了。 every() 在这里更合适吗?
    • @artparks 因为你想返回第一个匹配的项目some 应该结合作用域变量来完成这项工作。
    • 谢谢。这一切只是因为我不知道 foreach() 不能以这种方式使用:/ 因为这个函数将在每个页面请求上调用,它需要尽可能高效。有什么理由使用 some() 而不是老式的 for() 循环?
    • 不,some 会比老式的 for 循环慢(就像在我的第一个示例中一样),但我添加了一个使用 some 的示例。
    • 不是打高尔夫球的代码,但我添加了一种忍者方法,只需拨打n(language, translations)
    猜你喜欢
    • 2020-01-31
    • 2018-03-12
    • 2016-05-07
    • 2021-10-03
    • 1970-01-01
    • 2018-09-22
    • 1970-01-01
    相关资源
    最近更新 更多