Я пытаюсь проверить, существует ли пользователь (зарегистрированный в файле json).

К сожалению, я не могу найти правильное решение во всех переполнениях стека, которое дает мне простое «истина» в обратном вызове.

Версия, наиболее близкая к решению


Эксперимент V1:

let userExist; function check(){ console.log("CHECK!"); return userExist = true; } // check(); if this, return true... obvious. //// check if user exist server.readFileSync(filepath, 'utf8', (err, data) ={amp}gt; { let json = JSON.parse(data), userlist = json.allusers; for (let key in userlist) { if ( userlist[key].email == req.body.user_email ) { console.log("FINDED EQUAL"); check(); // return undefined ??? } } }); console.log("userExist value : " userExist); 

По-разному формулируются и отладки, но «true» никогда не возвращается.

примечание: да, JSON читается правильно. Если внутри readfile все работает, вы сразу же заметите те же письма.

 output: "undefined" Log: total bypassed 

Эксперимент V2:

В этом случае (с асинхронным чтением) он возвращает всю отладку (но «true» остается неопределенным)

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

  //// check if user exist server.readFile(filepath, 'utf8', (err, data) ={amp}gt; { let json = JSON.parse(data), userlist = json.allusers; for (let key in userlist) { if (/* json.allusers.hasOwnProperty(key) {amp}amp;{amp}amp;*/ userlist[key].email == req.body.user_email ) { console.log("FINDED EQUAL"); check(); } } }); var userExist; function check(userExist){ console.log("CHECK!"); return userExist=true; } console.log("userExist value : " userExist ""); 
 server listening on: 8080 userExist value : undefined CHECK! FINDED EQUAL 

Эксперимент V3:

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

Это позволило достичь упорядоченного кода, но, несмотря на это, невозможно дождаться результатов и экспортировать их из одной и той же функции (это потому, что сам узел является асинхронным! Поэтому он уже запущен!)

используя переменную «message», чтобы проверить, может ли он вернуть объект, я сделал это:

 //simple output tester var message; // create a promise let loopusers = new Promise( (resolve)={amp}gt;{ server.readFile( filepath, 'utf8', (err, data) ={amp}gt; { let json = JSON.parse(data), userlist = json.allusers, findedequal; console.log("CHECK USERS IN DB...for " userlist.length " elements"); // loop all items for (let key in userlist) { console.log("Analyzed key ::: " key); if ( userlist[key].email == req.body.user_email ) { console.log("CHECK : user isn't free"); findedequal=true; resolve(true); // return the result of promise } else if(key {amp}gt;= userlist.length-1 {amp}amp;{amp}amp; !findedequal ) { console.log("CHECK : User is free ;)"); resolve(false); // return the result of promise } } // call the action createuser(); }); }); // when promise finished --{amp}gt; start action async function createuser(message) { let userExist = await loopusers; console.log("userExist: " userExist); if(userExist) { message = { Server: "This user already exists, Try new e-mail..."}; } else { message = { Server: "Registration user -{amp}gt; completed..."}; } // return values return message; }; 

Также можно использовать классический синтаксис через «затем». Например:

 //simple output tester var message; // create a promise let loopusers = new Promise( (resolve)={amp}gt;{ ... }); loopusers.then( (response)={amp}gt;{ ... }) 

Затем я понял, что легко упростить еще больше, вызвав функции непосредственно из начальной:

  var message; // create a promise --{amp}gt; check json items server.readFile( filepath, 'utf8', (err, data) ={amp}gt; { let json = JSON.parse(data), userlist = json.allusers, findedequal; console.log("CHECK USERS IN DB...for " userlist.length " elements"); for (let key in userlist) { console.log("Analyzed key ::: " key); if ( userlist[key].email == req.body.user_email ) { console.log("CHECK : user isn't free"); findedequal=true; createuser(true); // call direct function whit params true } else if(key {amp}gt;= userlist.length-1 {amp}amp;{amp}amp; !findedequal ) { console.log("CHECK : User is free ;)"); createuser(false); // call direct function whit params false } } }); // start action function createuser(userExist) { if(userExist) { message = { Server: "This user already exists, Try new e-mail..."}; } else { message = { Server: "Registration user -{amp}gt; completed!"}; } // return values return message; }; 

отладка взята и написана

сообщение теряется вне функции aSync

Финал эксперимента V4! :

Наконец, после многих попыток решения! (Да … но знаю, что это не Async)

Если мы размещаем в переменной, чтение становится синхронным всей модели, и мы возвращаемся к простой

  let message, file = server.readFileSync(filepath, 'utf8'), // read sync json = JSON.parse(file), // now parse file userlist = json.allusers, // get your target container object userExist, findedequal; console.log("CHECK USERS IN DB...for " userlist.length " elements"); for (let key in userlist) { console.log("Analyzed key ::: " key); if ( userlist[key].email == req.body.user_email ) { console.log("CHECK : finded equal value on key [" key "] - user isn't free"); findedequal=true; userExist = true; } else if(key {amp}gt;= userlist.length-1 {amp}amp;{amp}amp; !findedequal ) { console.log("CHECK : User is free ;)"); userExist = false; } } if(userExist) { console.log("└ EXIT TO CHECK --{amp}gt; Can't create user, function stop."); message = { Server: "This user already exists, Try new e-mail..."}; } else { console.log("└ Exit to check --{amp}gt; New user registration ..."); message = { Server: "Registration user -{amp}gt; completed!"}; } } return message; 

Сейчас:

 It's all sync and all log is perfect all var is checked all return... return 

** Окончательные выводы: **

Можно ли получить переменную ASync в узле? Насколько я понимаю, пока … нет.

Узел асинхронен по своей природе, поэтому восстановление информации, которая не была сохранена, а затем восстановлена ​​из БД, остается среди вещей, которые нужно сделать, и становится невосстановимым, если вы используете ее, как в этом посте.

Однако … если цель состоит в том, чтобы сделать чтение файла синхронным, ответ был бы проще, чем ожидалось.


Особая благодарность: Barmar; Остин Лихили; C.Gochev;

Проблема в том, что вы вызываете console.log («значение userExist:» userExist «»); слишком рано. В тот момент, когда вы вызываете эту строку, userExist еще не определен. Это связано с тем, что функция server.readFile () требует обратного вызова, и эта функция обратного вызова выполняется после прочтения файла. Однако чтение файлов часто занимает много времени, поэтому программа продолжает работать. Он выполняет console.log («значение userExist:» userExist «»); и затем возвращается к функции обратного вызова и определяет userExist как true.

Если вы хотите больше информации о том, что обратные вызовы, посмотрите на ссылку ниже. Обратные вызовы являются определяющей особенностью Nodejs, и их понимание необходимо для любого веб-сайта Node.

https://medium.com/better-programming/callbacks-in-node-js-how-why-when-ac293f0403ca

Попробуйте что-то вроде этого.

 let userExist; function check(){ console.log("CHECK!"); return userExist = true; } // check(); if this, return true... obvious. //// check if user exist server.readFileSync(filepath, 'utf8', (err, data) ={amp}gt; { let json = JSON.parse(data), userlist = json.allusers; for (let key in userlist) { if ( userlist[key].email == req.body.user_email ) { console.log("FINDED EQUAL"); check(); // return undefined ??? console.log("userExist value : " userExist); } } });