Это очень запутанная тема, и мне потребовалось некоторое время, чтобы действительно понять, почему то, что вы спрашиваете, просто невозможно (по крайней мере, точно так, как вы спрашиваете).Для примеров я буду использовать Python Django и Node.js для сравнения.
Sync
def synchronous():
print('foo') //this will always print first
print('bar')
def getUsers():
with connection.cursor() as cursor:
cursor.execute('SELECT * FROM USERS') //this query is executed
users = cursor.fetchall()
print('foo') //this doesn't trigger until your server gets a response from the db, and users is defined
print(users)
Async
function asynchronous() {
console.log('foo'); //this will also always print first
console.log('bar');
}
function getUsers() {
var connection = mysql.createConnection(config);
connection.query('SELECT * FROM USERS', function(error, users) { //this is a "callback"
console.log(users); //this will print
//everything inside of here will be postponed until your server gets a response from the db
});
console.log('foo') //this will print before the console.log above
console.log(users); //this will print undefined
//this is executed before the query results are in and will be undefined since the "users" object doesn't exist yet.
}
A callback isпросто функция, которую должен запускать ваш сервер, как только вы получите ответ.Обычно мы используем фактическое слово «обратный вызов», например:
function getUsers(callback) {
var connection = mysql.createConnection(config);
connection.query('SELECT * FROM USERS', function(error, users) {
if (error) throw error; //always do your error handling on the same page as your query. Its much cleaner that way
callback(users) //server asks what to do with the "users" object you requested
});
}
Теперь где-нибудь еще на вашем сервере:
getUsers(function(users) {// the callback gets called here
console.log(users); //do what you want with users here
});
Функция getUsers
принимает некоторую другую функцию (т.е.callback) в качестве аргумента и выполняет эту функцию после выполнения запроса.Если вы хотите сделать то же самое, не используя слово «обратный вызов», вы можете использовать функцию await / async, такую как fsociety, или вы явно пишете свой код, а не создаете функции, которые принимают другие функции в качестве аргументов.
Эта функциональность идентична приведенному выше коду:
var connection = mysql.createConnection(config);
connection.query('SELECT * FROM USERS', function(error, users) {
if (error) throw error;
console.log(users);
});
Ад обратного вызова неизбежен, но на самом деле это не так уж и плохо, как только вы его освоите.