Вам придется использовать функции обратного вызова или обещания / асинхронные. Вот как это можно написать с помощью обратных вызовов:
const mysql = require('mysql');
const retryLimit = 50;
const connection = mysql.createConnection({
database: 'test',
host: 'localhost',
password: 'hunter2',
user: 'dave',
});
function getData(attempts, cb) {
if (attempts < retryLimit) { // we haven't exausted our attempts yet
const code = generatePrizeCode();
connection.query('SELECT * FROM user WHERE code = ?', code, (err, result) => {
if (err) {
return cb(err);
}
if (result.length > 0) { // code already exists
getData(attempts + 1, cb); // recurse
} else { // this is a new code
cb(null, code); // return the new code via the callback function
}
});
} else { // we have exausted our attempts
return cb(new Error('retry limit exceeded'));
}
}
getData(0, (err, code) => {
// do what you want here, e.g., console.log(code)
connection.end();
});
Обратите внимание, что это может привести к сбою узла, если вы выполняете слишком много раз и превышаете максимальный стек вызовов. Одним из способов решения этой проблемы является вызов setImmediate или setTimeout вместо прямого повторения. Вместо строки
getData(attempts + 1, cb); // recurse
использование
setImmediate(() => {
getData(attempts + 1, cb); // recurse
});
или
// recurse, using setImmediate every 1000th time
if (attempts % 1000 === 0) {
setImmediate(() => {
getData(attempts + 1, cb); // recurse
});
} else {
getData(attempts + 1, cb); // recurse
}
Использование обещаний и стиля async / await могло бы сильно это очистить и, вероятно, больше походить на то, к чему вы привыкли (обратите внимание, что здесь используется библиотека promise-mysql
):
const mysql = require('promise-mysql');
async function getData(connection) {
const retryLimit = 50;
for (let i = 0; i < retryLimit; i++) {
const code = generatePrizeCode();
const result = await connection.query('SELECT * FROM user WHERE code = ?', code);
if (result.length === 0) { // this code doesn't exist yet
return code;
}
}
throw new Error('retry limit exceeded');
}
(async () => {
try {
const connection = await mysql.createConnection({
database: 'test',
host: 'localhost',
password: 'hunter2',
user: 'dave',
});
try {
const code = await getData(connection);
// do what you want here, e.g., console.log(code)
} finally {
connection.end();
}
} catch (err) {
console.log(err);
}
})();