Почему массив не передается из этой функции при обратном вызове discord.js - PullRequest
0 голосов
/ 06 июня 2019

Я не уверен, почему массив, созданный в этом цикле внутри асинхронной функции, не проходит, когда я вызываю его позже в коде.

Я сделал асинхронные функции, которые ожидаютРеакции работают правильно, затем обычные функции синхронизации, которые задают вопросы и ждут ответа от пользователя, но никогда не выполняют асинхронную функцию, которая ожидает ответа и передает значение для использования позже.Итак, я не уверен, что мне здесь не хватает.Я довольно плохо знаком с асинхронными функциями.

Следующая функция делает несколько вещей.Он спрашивает пользователя, какие имена карт должны быть добавлены в колоду, которую он только что сделал (созданный другой функцией в коде).Когда пользователь предоставляет список названий карт, код проверяет каждую карту в отдельности, чтобы увидеть, существует ли карта в базе данных.Если он находит карту, он помещает ее в массив «совпавших карт».Если карта не может быть добавлена, она отправляет сообщение Discord о том, что оно не найдено.

Он добавляет найденные карты в массив, потому что я записываю его на консоль, и он показывает массив с картами, которые, как я знаю, существуют, и игнорирует тот, который вышел из строя.

Проблема в том, что когда я пытаюсь использовать массив, который я позже передал в коде, он действует так, как будто массив пуст.Я не уверен, почему значение "matchedcards" не передается должным образом.

async function cardExists() {

let msg = await message.author.send(`Please provide the cardnames that you would like to add to '${userdeckname}'.\n\n**NOTE:** Please separate each card with a comma and space, like so "Pact of Darkness, Aquos Slam, Karmic Balance"`)

const filter = m => m.author.id === message.author.id
const reply = await msg.channel.awaitMessages(filter, { max: 1 })
 .catch(console.error);

let cardsToAdd = reply.first()

let usercardnamearray = cardsToAdd.content.split(", ")

let matchedcards = []

usercardnamearray.forEach(function(element) {
con.query(`SELECT cardname FROM card_info where cardname = '${element}'`, (error, rows) => {

if (rows == [] || rows == ""){
message.author.send(`The card **${element}** could not be added. Please check your spelling, capitalization and enter your list of cards again!`)
} else if (rows[0] != undefined || rows[0] != null || rows[0] != "" || rows[0]){

matchedcards.push(element)
console.log(`'${element}' found in database!`)
console.log(matchedcards)
}
})
})
console.log(matchedcards)
return matchedcards;
}

Тогда я использую код позже ... Я не уверен, что он запускается слишком раноили что

(async function(){
//Some other if/else statements, each being determined by different functions stated earlier in the code... code below is inside the if else statement that worked fine until this variable doesn't get passed

let matchedcards = await cardExists();
if (matchedcards.length > 0){
matchedcards.join(", ")
message.author.send(`You have added **${matchedcards}** to ${userdeckname}!`) 
let sql2 = `INSERT INTO devdecks (creatoruser, creatorid, deckname, cardnames) VALUES ('${author.username}', ${author.id}, '${userdeckname}', '${matchedcards}')`
con.query(sql2)
}

Функция работает, как и предполагалось, как я уже говорил, я просто получаю такой ответ вместо этого "Вы добавили ** в тестовую колоду 21!"дискордировать вместо карт массива / списка, которые были успешными ... Я надеюсь, что я не пропускаю что-то маленькое, что я брошу лицом к лицу и скажу, что я глуп по ... ... 1015 *

Заранее спасибо за вашу помощь!

Ответы [ 2 ]

1 голос
/ 07 июня 2019

Из-за способа построения forEach() его не волнуют возвращаемые значения. Он просто выполняет код и переходит , не дожидаясь завершения вашего обратного вызова . Поэтому ваша функция продолжает работать и возвращает массив до того, как в него можно будет вставить значения.

Я предлагаю использовать for цикл , как показано ниже. В отличие от forEach(), у него будет терпение дождаться вашего кода и дать ожидаемые результаты.

const arr = [5, 10, 15];

console.log(`BEFORE: ${arr.join(', ')}`);

for (let i = 0; i < arr.length; i++) {
  console.log(`CHANGING: ${arr[i]}`);

  arr[i]++;
}

console.log(`AFTER: ${arr.join(', ')}`);
0 голосов
/ 08 июня 2019

После некоторой помощи от комментариев и ответов @ slothiful, я провел много испытаний с разными вещами.В конце концов я обнаружил, что сам запрос вызывает проблемы ... Поэтому я вытащил запрос и поместил его в верхнюю часть файла кода примерно так ...

con.query(`SELECT cardname FROM card_info`, (error, rows, fields) =>{ 

            let cardsList = []
            for (var i in rows) {
                cardsList.push(rows[i].cardname)
            }
            console.log(cardsList)

Это сделало большой массивкаждое название карты в таблице.Это также позволило бы мне позже использовать .indexOf, просто чтобы посмотреть, существует ли предложенное имя карты ...

Окончательная функция была следующей ...

async function cardExists() {

let msg = await message.author.send(`Please provide the cardnames that you would like to add to '${userdeckname}'.\n\n**NOTE:** Please separate each card with a comma and space, like so "Pact of Darkness, Aquos Slam, Karmic Balance"`)

const filter = m => m.author.id === message.author.id
const reply = await msg.channel.awaitMessages(filter, { max: 1 })
.catch(console.error);

let cardsToAdd = await reply.first()

let usercardnamearray = await cardsToAdd.content.split(", ")

let matchedcards = []
let unmatchedcards = []

for (let i = 0; i < usercardnamearray.length; i++) {

let found = cardsList.indexOf(`${usercardnamearray[i]}`)
console.log(found)

if (found >= 0) {
matchedcards.push(usercardnamearray[i])
} else if (found == -1){
unmatchedcards.push(usercardnamearray[i])
}     
}
console.log('Finished!')
return await [matchedcards, unmatchedcards]
}

А теперьзначения для совпавших карточек и непарных карточек наконец были переданы обратному вызову позже.

let cards = await cardExists();  
let matchedcards = await cards[0]
let unmatchedcards = await cards[1]

message.author.send(await `You have added **${matchedcards.join(", ")}** to ${userdeckname}!`) 
message.author.send(await `The card **${unmatchedcards.join(", ")}** could **NOT** be added. Please check your spelling, capitalization and enter your list of cards again!`)
let sql2 = await `INSERT INTO devdecks (creatoruser, creatorid, deckname, cardnames) VALUES ('${author.username}', ${author.id}, '${userdeckname}', '${matchedcards.join(", ")}')`
await con.query(sql2)
}

Я не знаю, является ли это по сути ответом настолько, насколько это обходной путь, чтобы получить то, что мне нужно ...Хотелось бы знать, почему запрос внутри цикла в асинхронной функции вызвал слишком раннюю передачу совпавших и непарных карточек.Может быть, запросы синхронны?Это было бы для меня новостью, но у меня, возможно, только что было комбо, которое не работало хорошо, в то время как цикл, запрос и оператор if / else вместе вызывают проблемы.Я не знаю, но у меня все получилось!Еще раз спасибо @slothiful за помощь!

...