循环中的节点 JS 回调

Posted

技术标签:

【中文标题】循环中的节点 JS 回调【英文标题】:Node JS callbacks in a while loop 【发布时间】:2021-07-30 15:15:53 【问题描述】:

我有一个带有 id 表的 mysql 数据库,它使用 nanoid 模块存储迄今为止生成的所有唯一 ID。我已经实现了以下代码来生成一个不在表中的唯一 id。

//sql library
const mysql = require('mysql');
const sql_obj = require(__dirname + '/../secret/mysql.json');


//nanoid library
const  customAlphabet  = require('nanoid');
const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
const nanoid = customAlphabet(alphabet, 30);

function uniqueid()
    let found = 0;
    let conn = mysql.createConnection(sql_obj);
    while (found === 0)
        let id = nanoid();
        conn.connect(function(err)
            if (err)
                found = 2;
            
            else
                conn.query("SELECT * FROM id WHERE value = " + mysql.escape(id),function(err,result,fields)
                    if (err)
                        found = 2;
                    
                    else
                        if (result.length === 0)
                            found = 1;
                        
                    
                )
            
        )
    
    if (found === 2)
        return error: 1,ret: null;
    
    else if (found === 1)
        return error: 0,ret: id;
    


console.log(uniqueid());

我知道,我的实现是错误的。因为回调本质上是异步的,while 循环永远不会结束,因此我得到了错误 JavaScript heap out of memory。 我浏览了网络上的许多文章来解决这个问题,但无法解决。主要问题是函数 uniqueid 应该返回一些值,因为我是从其他 javascript 文件调用它。 感谢您的帮助

【问题讨论】:

【参考方案1】:

我认为防止这种情况发生的最好方法是使用async/await

我答应了你的 mySql 连接。您可以将您的queryvalues 发送给该函数。

    //sql library
    const mysql = require('mysql');
    const sql_obj = require(__dirname + '/../secret/mysql.json');


    //nanoid library
    const  customAlphabet  = require('nanoid');
    const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    const nanoid = customAlphabet(alphabet, 30);

    let db = (query, values = null) =>   
        return new Promise((resolve, reject) => 
            let conn = mysql.createConnection(sql_obj);
            conn.connect(function (err) 
                if (err) 
                    reject(err);
                
                else 
                    conn.query(query + values, function (err, result, fields) 
                        if (err) 
                            reject(err);
                            return;
                        
                        else 
                            if (result.length === 0) 
                                resolve();
                            
                        
                    )
                
            )
        )
    

    async function uniqueid() 
        while (found === 0) 
            let id = nanoid();
            try 
                await db("SELECT * FROM id WHERE value =", mysql.escape(id));
                return  error: 0, ret: id ;

             catch (error) 
                return  error: 1, ret: null ;
            
        
    

    console.log(uniqueid());


【讨论】:

以上是关于循环中的节点 JS 回调的主要内容,如果未能解决你的问题,请参考以下文章

我的回调与预期的节点 js 不同

有关使用node-postgres和render page的节点js中的回调的问题

如何将节点中的异步回调添加到函数调用?

js DOM操作

如何在 JS(节点)中使用回调来等待 Async 函数完成后再继续?

如何在节点 js 中正确使用等待/异步与 for 循环