javascript - 回调和/或承诺 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");
}
}
请温柔一点,我已经在其他帖子上大发雷霆,但似乎我需要更多解释......
解决方案
异步逻辑是新手经常被绊倒的地方。但是,它基本上归结为这样做:
同步代码示例:(假设 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]);
(有可能我没有完全理解您希望原始代码如何工作,因此请以一粒盐为例。它显示了原理,但您必须对其进行调整以满足您的需要)
推荐阅读
- dart - Flutter:子小部件(作为构造函数参数传递)给父小部件,向父小部件发出事件?
- greenplum - Greenplum - 主节点是瓶颈?
- css - 不能用组合框省略轮廓
- php - 用新外键替换列值的方法?
- c# - AutoMapper 高级映射
- powershell - 无法获取 Item 的字符串属性并将其转换为 Int
- java - 我的带有 FirebaseRecyclerAdapter 的 RecyclerView 没有在屏幕上显示任何内容
- python - 类型错误:序列项 0:预期的 str 实例,在 Django 应用程序中添加新闻项时找到元组
- sql-server - 如何获取与条件匹配的行的总和
- reactjs - 使用情感时如何解决汇总构建错误:@emotion\memoize\dist\memoize.cjs.js 未导出“默认”