当需要同步时,NodeJS需要具有异步功能

时间:2017-01-01 16:29:18

标签: javascript node.js asynchronous require synchronous

我有以下代码

var utils = require(`${__dirname}/../../utils/utils.js`);
...
let object = utils.parse(input);
    if (object === undefined){
        let helper = utils.recognize(input);
        msg.channel.sendMessage("\"" + input + "\" not recognized. Did you mean \"" + helper[0] + "\"?");
        object = utils.parse(helper[0]);
    }
//code related to object
console.log(object.strLength);

其中"解析"尝试将输入与数据库中的对象进行匹配,并且"识别"如果输入拼写错误(Levenshtein),则尝试找到最佳匹配(以及其他信息,例如匹配的距离)。

目前问题是代码是异步运行的; " object.strLength"在utils.recognize()返回值之前返回undefined。如果我将recogn()和parse()函数复制/粘贴到文件中,那么代码将同步运行,我不会遇到任何问题。但是,我宁愿将这些函数保存在单独的文件中,因为我在其他文件中重复使用它们。

有没有办法指定utils中的函数必须同步?我知道有些库可以将异步转换为同步,但我更喜欢使用尽可能少的库来帮助它。我试图让识别函数返回一个Promise但它最终变成了乱七八糟的混乱

编辑:这里解析。我认为没有必要回答这个问题,所以我最初没有把它包括在内:

var db = require(`${__dirname}/../data/database.js`);
...
var parse = (input) => {
    let output = db[output];
    if (output === null) {
        Object.keys(db).forEach((item) => {
            if (db[item].num === parseInt(input) || (db[item].color + db[item].type === input)){
                output = db[item];
                return false;
            }
        });      
    }
    return output;
}

1 个答案:

答案 0 :(得分:0)

我解决了这个问题,谢谢大家。这里出了什么问题,那就是识别()。我最初没有为它显示代码是错误的。

原认:

var recognize = (item) => {

//iterate through our databases and get a best fit
let bestItem = null;
let bestScore = 99999; //arbitrary large number
//let bestType = null;

//found algorithm online by milot-mirdita
var levenshtein = function(a, b) {
    if (a.length == 0) { return b.length; } 
    if (b.length == 0) { return a.length; }

    // swap to save some memory O(min(a,b)) instead of O(a)
    if(a.length > b.length) {
        let tmp = a;
        a = b;
        b = tmp;
    }

    let row = [];
    for(let i = 0; i <= a.length; i++) {
        row[i] = i;
    }

    for (let i = 1; i <= b.length; i++) {
        let prev = i;
        for (let j = 1; j <= a.length; j++) {
            let val;
            if (b.charAt(i-1) == a.charAt(j-1)) {
                val = row[j-1]; // match
            } else {
                val = Math.min(row[j-1] + 1, // substitution
                        prev + 1,     // insertion
                        row[j] + 1);  // deletion
            }
            row[j - 1] = prev;
            prev = val;
        }
        row[a.length] = prev;
    }
    return row[a.length];
}   

//putting this here would make the code work
//console.log("hi");

Object.keys(db).forEach((key) => {
    if (levenshtein(item, key) < bestScore) {
        bestItem = key;
        bestScore = levenshtein(item, key);
    }
});

return [bestItem, bestScore];

}

我的解决方案是将levenshtein函数移到识别函数之外,所以如果我想,我可以从另一个函数调用levenshtein

@ user949300和@Robert Moskal,我将forEach循环更改为let ... in循环。没有功能差异(据我所知),但代码确实看起来更干净。

@Thomas,我解决了let output = db[output];问题,哎呀。

再次感谢您的所有帮助,我很感激。祝新年快乐