Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 21.01.2018, 15:46
Новичок на форуме
Отправить личное сообщение для artichek Посмотреть профиль Найти все сообщения от artichek
 
Регистрация: 21.01.2018
Сообщений: 2

Callback Hell
Приветствую. Нужно чтобы функция, если аккаунт существует, возвращала 1, если нет - 0. При первом вызове выдаёт undefined, дальше как нужно. Видимо что-то с обратными вызовами, помогите исправить:
const mysql = require('mysql')
let r
function isRegistered(id){
    var sel_query = con.query('SELECT * FROM `users` WHERE `userid`= ?', id, function GET(error, results, fields) {
        if (results.length != 0) {
            r = 1
        }
        else {
            r = 0
        }
        return r
    })
    return r
}
Ответить с цитированием
  #2 (permalink)  
Старый 22.01.2018, 11:48
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,584

Колбэки работают примерно так:
function isRegistered(id, success, error){
    var sel_query = con.query('SELECT * FROM `users` WHERE `userid`= ?', id, function GET(error, results, fields) {
        if(error) return error(error, id);
        if(!results.length) return error(0, id);
        return success(results.length, id);
    })
}

function coninueIfRegistered(count, id){
  //дальнейший код если зарегестрирован
}

function coninueIfNotRegistered(reason, id){
  //дальнейший код если не зарегестрирован
}


isRegistered(id, coninueIfRegistered, coninueIfNotRegistered);

Можно пошаманить с промисами и async await, но пока с этим не разберётесь - лучше не надо.
__________________
29375, 35

Последний раз редактировалось Aetae, 22.01.2018 в 11:51.
Ответить с цитированием
  #3 (permalink)  
Старый 22.01.2018, 12:05
Профессор
Отправить личное сообщение для Audaxviator Посмотреть профиль Найти все сообщения от Audaxviator
 
Регистрация: 28.04.2017
Сообщений: 214

isRegistered(bla-bla);

async function isRegistered(id) {
  var sel_query = await new Promise( resolve => {
    con.query('SELECT * FROM `users` WHERE `userid`= ?', id, function(error, results) {
      if(err) console.error(err);
      resolve(results);
    });
  }).then( result => {
    return result;
  };
  if(sel_query.length != 0) {
    console.log(1, sel_query);
  } else {
    console.log(0);
  }
}
Ответить с цитированием
  #4 (permalink)  
Старый 22.01.2018, 12:10
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,584

Audaxviator, тогда уж так:

const mysql = require('mysql')

async function isRegistered(id){
  var r = await new Promise(resolve => con.query('SELECT * FROM `users` WHERE `userid`= ?', id, function(err, results) {
    if(err || !results.length) return resolve(false);
    return resolve(true);
  }));                                  
  return r
}


(async function(){
  //основной код тут  

  let r = await isRegistered(id);
  //...
}());

Только человеку не понимающему стути коллбэков это только вред принесёт.)
__________________
29375, 35

Последний раз редактировалось Aetae, 22.01.2018 в 12:13.
Ответить с цитированием
  #5 (permalink)  
Старый 22.01.2018, 12:18
Новичок на форуме
Отправить личное сообщение для artichek Посмотреть профиль Найти все сообщения от artichek
 
Регистрация: 21.01.2018
Сообщений: 2

@Aetae, @Audaxviator, сердечно благодарю за помощь, пойду учить матчасть
Ответить с цитированием
  #6 (permalink)  
Старый 19.02.2018, 10:02
Аватар для Валерия_05
Новичок на форуме
Отправить личное сообщение для Валерия_05 Посмотреть профиль Найти все сообщения от Валерия_05
 
Регистрация: 18.02.2018
Сообщений: 9

Aetae, скажите, а разве из js можно работать с БД? Через аякс + PHP понятно, можно.
А выше какие-то query запросы прямо в js идут)) Это как так? Разве так можно?
Для подключения к БД ведь логин и пароль нужен будет и его ведь не спрячешь в js. Это не безопасно.
Ответить с цитированием
  #7 (permalink)  
Старый 19.02.2018, 10:04
Аватар для Валерия_05
Новичок на форуме
Отправить личное сообщение для Валерия_05 Посмотреть профиль Найти все сообщения от Валерия_05
 
Регистрация: 18.02.2018
Сообщений: 9

А, всё я поняла. Это NodeJS там наверное всё иначе работает.
Извините.
Ответить с цитированием
  #8 (permalink)  
Старый 19.02.2018, 12:50
Профессор
Отправить личное сообщение для Audaxviator Посмотреть профиль Найти все сообщения от Audaxviator
 
Регистрация: 28.04.2017
Сообщений: 214

Тэкс. Объясняем "на пальцах" суть колбеков в асинхронных методах.
Вот обычная советская функция, которая присваивает объявленной перед её вызовом переменной значение - так, "как все привыкли":
function foo() {
  a = 'aaa';
}

var a;
foo();
console.log(a);    // 'aaa'

Полный успех.
А давайте сделаем присвоение значения переменной а - асинхронным, вот так:
function foo() {
  process.nextTick( () => {
    a = 'aaa';
  });
}

var a;
foo();
console.log(a);    // undefined

Ошибки не случилось - то есть функция переменную видела, к ней благополучно обращалась, - но в текущем "тике" переменной значение, естественно, не присвоено. Причём, оно было ваабщета присвоено - но нам оказалось уже недоступно.
А давайте посмотрим, есть ли оно в следующем тике?
function foo() {
  process.nextTick( () => {
    a = 'aaa';
  });
}
 
var a;
foo();
console.log(a);  // undefined

process.nextTick ( () => {
  console.log(a);  // 'aaa'
});

Таки есть!
И чтобы нам её (переменную с присвоенным значением) всё таки добыть и употребить, как раз и потребуется колбек-функция. Тырц:
function foo(cb) {
  setImmediate( () => {  // setImmediate - это правильная директива для асинхронного исполнения
    a = 'aaa';
    cb(a);
  });
}

var a;
foo( data => {
  console.log(data);  // 'aaa'
});
console.log(a);  // а тут, понятно, как и прошлый раз - undefined

Причём, сначала-то будет выведено undefined из последней строчки, а потом - 'aaa' из колбека.
Вот и вся несложная мудрость. Из которой, надеюсь, должно быть понятно, что любой асинхронный метод любую переменную "снаружи" взять-то может - а вот воспользоваться тем, что он с ней сделает, можно только "внутри": либо внутри собственно колбека этого метода, либо внутри промиса (в который обернут, опять же, вызов этого метода с вызовом его колбека) - но "внутри", и не иначе.
В "борьбе с асинхронностью" приходится всё время придумывать конструкции для добывания нужных значений в нужном месте. И это хорошо.
Извените за внимание.

Последний раз редактировалось Audaxviator, 29.03.2018 в 16:38.
Ответить с цитированием
  #9 (permalink)  
Старый 19.02.2018, 13:40
Аватар для Alexandroppolus
Профессор
Отправить личное сообщение для Alexandroppolus Посмотреть профиль Найти все сообщения от Alexandroppolus
 
Регистрация: 25.10.2016
Сообщений: 1,012

Audaxviator,
не совсем понял суть замены process.nextTick на setImmediate (и комментария к последней)
Ответить с цитированием
  #10 (permalink)  
Старый 19.02.2018, 14:28
Профессор
Отправить личное сообщение для Audaxviator Посмотреть профиль Найти все сообщения от Audaxviator
 
Регистрация: 28.04.2017
Сообщений: 214

process.nextTick было типа в демонстрационных целях - буквально "в следующем тике". Нопремер, setTimeout - это тот же nextTick, но с минимальной задержкой 4 миллисекунды (если написать 0 - всё равно будет 4). Но во-первых, задержка при асинхронном исполнении не нужна, а во-вторых, nextTick даёт приоритет первому некст-тику в коде. А если несколько асинхронных операций?
Короче, это не замена, а использование правильной для асинхронного исполнения функции во втором случае.
Ну, или чтобы всех запутать или заинтриговать.

(Словом, в этом "примитивном" примере будет одинаково работать и то, и то. А "в реальной жизни" используется setImmediate. Оно когда-то было предложено, вроде бы, Микрософтом, и в ихнем Эксплорере, в интерпретаторе JavaScript, присутствует (в других браузерах - не знаю, не проверял). И в Node - конечно, было сразу нативно вписано.)

Последний раз редактировалось Audaxviator, 19.02.2018 в 17:26.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Можно ли так использовать callback функции? Denwf Node.JS 2 14.03.2017 10:20
Работы с callback функциями jenek_34 Общие вопросы Javascript 13 25.03.2015 12:03
Работа с textarea Rompo Events/DOM/Window 14 16.12.2013 17:41
Callback работает не так как я от него жду singaporian Общие вопросы Javascript 3 14.08.2013 00:42
В callback функции теряется контекст. Как это обойти? xintrea AJAX и COMET 4 02.06.2013 11:40