首页 > 解决方案 > 回调和/或承诺 javascript

问题描述

自从我试图理解我的错误以来已经 2 天了。到目前为止,我了解到的是,我将永远无法绕过“未定义”返回值,因为我无法理解回调或承诺......我骑了所有的 poste,做了一些简单的例子,但我不知道如何让它发生在我的代码上......

function realloot(data){
    return data;
    console.log(`${data}`);
    }
 
 
function lootbox_openning(callback, user, type, nombre){
 
let sqlQueryopenbox = `SELECT item_qty FROM users_items WHERE discord_id = '${user}' AND item_id = ${type};`
 
let token_won=0;
let real_token_won=0;
let common_pp_looted = 0;
let rare_pp_looted = 0;
let epic_pp_looted = 0;
 
        db.query(sqlQueryopenbox, (err, rows) => {
            
            let user_box_real_qty = rows[0].item_qty;
            let sql;
        
            if (err) {
                real_token_won="sql error";
                throw err;
                }
                
            if (nombre > user_box_real_qty){real_token_won="error number";}
            
            else {
                //function open
                
                if (type==1) { 
                
                    for (var i = 0; i <= nombre; i++){
                        token_won=little_box_open();
                        real_token_won=real_token_won+token_won;
                    }
                    var myreturn = callback(real_token_won);
                    console.log(`${myreturn}`);
                    return myreturn;
                }
                if (type==2) {}
                if (type==3) {}
            }
        
        });
 
}
 
 
//this is a bot discord so huge on.message here...
 
 
 
            case "open":
                if (!args[1]) return message.channel.send('please give value box | bigbox');
                
                if (args[1] ==='box' ){
                    if (!args[2]) {message.channel.send ("Specify number please");}
                    if (args[2]) {
                        var number = parseInt(args[2]);
                        if (Number.isInteger(number)){
                            message.channel.send ("You re openning "+args[2]+" boxes");
                            **var token_won = lootbox_openning(realloot, message.author.id, 1, args[2]);** //PROBLEM IS HERE 
                            if (token_won==="error number"){message.channel.send ("Vous n'avez pas assez de box !");}
                            else {message.channel.send ("you won : "+token_won+" tokens !");}
                            }
                        else message.channel.send ("Give a valid number");
                        }
                    }

请温柔一点,我已经在其他帖子上大发雷霆,但似乎我需要更多解释......

标签: javascriptsqlpromisecallback

解决方案


异步逻辑是新手经常被绊倒的地方。但是,它基本上归结为这样做:

同步代码示例:(假设 db.query() 被编写为同步函数,但事实并非如此)

function doQuery(id) {
  let res = db.query(`SELECT * FROM table WHERE id=${id}`)
  return res
}

异步代码示例(使用 db.query() 作为异步函数)

function doQuery(id, callback) {
  db.query(`SELECT * FROM table WHERE id=${id}`, function(res) {
    callback(res)
  })
}

这里的主要区别是return res你必须做而不是做callback(res)。使用异步代码时总是会出现这种情况。

重要的是要注意,一旦您进入异步世界,就永远无法回到同步世界。即这是不可能的:

// some sync logic
let resultOfAsyncOperation = someAsyncFunction()
// some sync logic

一旦你处理了回调,你就必须到处使用回调。这是因为异步函数的用户本身必须是异步的。唯一的例外是,如果您不关心返回什么或何时返回,您只希望它启动并执行一些任务。

因此,这就是这些原则如何应用于您的特定代码块的方式。这段代码正是我所描述的问题 - 您正在尝试在同步逻辑中使用异步函数。

var number = parseInt(args[2]);
if (Number.isInteger(number)) {
    message.channel.send("You re openning " + args[2] + " boxes"); **
    var token_won = lootbox_openning(realloot, message.author.id, 1, args[2]); ** //PROBLEM IS HERE 
    if (token_won === "error number") {
        message.channel.send("Vous n'avez pas assez de box !");
    } else {
        message.channel.send("you won : " + token_won + " tokens !");
    }
} else message.channel.send("Give a valid number");

您必须将这段代码也转换为异步的,如下所示:

message.channel.send("You re openning " + args[2] + " boxes");
function callback(token_won) {
  realloot(token_won)
  if (token_won === "error number") {
    message.channel.send("Vous n'avez pas assez de box !");
  } else {
    message.channel.send("you won : " + token_won + " tokens !");
  }
}
lootbox_openning(callback, message.author.id, 1, args[2]);

(有可能我没有完全理解您希望原始代码如何工作,因此请以一粒盐为例。它显示了原理,但您必须对其进行调整以满足您的需要)


推荐阅读