promise (async await)
Уважаемые господа!
Необходимо осуществить чтение из БД и при этом нужно дождаться результата. есть класс MSSQL и у него функция async readQuery( option ){ ....... здесь формируем и выполняем запрос ждем его выполнения return result; //--- результат запроса (массив объектов) } все замечательно. при выполнении функции все происходит как нужно но дело в том, что async сам по себе промис, и выполняется отдельно. т.е. в том месте где нужно обратится к функции: let query = { query:'select * from dbo.spin' } let result = global.mssql.readQuery(query); //--- а вот тут не ждем //--- а сюда ходить без результата нельзя ну и соответственно result получается не тот, который должна вернуть функция, а объект промиса. Собственно вопрос - как дождаться выполнения этой функции? Спасибо |
т.е. получается ли так, что в том месте где я вызываю эту функцию и мне необходимо дожидаться результата я должен объявить async (функция откуда делается вызов) и применять await ?
|
fxobject, можно сделать свою async-функцию и потом в ней все вызывать как await-функции...
|
fxobject, вот примерчик такого
https://habr.com/ru/post/334772/ |
Увы вопрос не понят. Сейчас он уже даже не в технической а в концептуальной форме.
функция А(){ ФункцияКоторуюНужноПодожд ать(); //" асинхронная " //--- здесь функция которую нужно подождать точно завершена следующий код } Функцию А точно нельзя делать async Вот вопрос ставится именно так. Все остальные комбинации (технический) как реализовать, async и всякое такое не вариант. На вопрос - как? Ответ скорей всего никак. можно организовать некую переменную для контроля завершения. например так: let finished = false; ФункцияКоторуюНужноПодожд ать(); while( finished ){} Но так тоже не пойдет - JS это не многопоточная среда. Чтобы выполнился "асинхронный" (на самом деле он ни какой не асинхронный) код необходимо закончить цикл и уйти в ядро JS. Потому как пока крутится цикл - все так называемые асинхронные задачи остановлены. Если есть вариант в цикле отдать управление очереди JS и потом получить обратно в то же самое место, то задачу решить в такой постановке удастся. Например let finished = false; ФункцияКоторуюНужноПодожд ать(); while( finished ){ ОтдатьУправлениеОчередиJS() ; } |
Цитата:
Но такого кода нет. Т.е. вот примерно так А(){ B(); //--- вот тут что будет? подразумевается что с завершена! } B(){ c() - и вот тут типа своя функция которая ждет. А что будет с кодом выше? В функции А? } |
Цитата:
Цитата:
Если не надо ждать окончания асинхронной функции, значит не надо вызывать ее с await. Просто вызвать и все, а как она сработает, так и сработает. |
Цитата:
Цитата:
let result = await global.mssql.readQuery(query); |
так. постараюсь еще раз объяснить свою позицию.
function А(){ //--- где то там вызовется асинхинхронная функция B(); //Точка 1 вот тут нужны результаты асинхронной функции } B(){ что то делаем //--- где то там вызовется асинхинхронная функция С(); // Точка 2 а тут тем более нужны результаты асинхронной функции } C(){ //-- еще раз что то делаем D() АСИНХРОННО!!! // Точка 3 // надо дождаться D ниже код зависит от результата // не только ниже но и по стеку вызовов функции все остальные тоже // зависят и любой ваш async запланируем выполнение D (ского бы вы не ставили await ов), но сразу же D завершится с возвратом промиса и пойдет по коду дальше..... выйдет из всех процедур (а тама ждут результата) и только вывалившись в ядро JS (попав в очередь задач) начнет выполнять D. завершит D передаст результаты then и что потом? А мне они нужны в точке Точка 1,2,3 } Господа, я понимаю что такое await и все что с этим связано - вникните в постановку задачи. Если идти по вашему предложению, тогда всю логику (Точка 1,2,3) необходимо запихивать в колбэк (это собственно и есть ваш промис) для асинхронной функции. Это понятно, даже правильно. В таких случаях кроме promise есть и другие интересные механизмы.... вопрос встал чисто теоретически - ну вот захотелось. можно или нет? |
Цитата:
Есть еще события. Их можно назначить при вызове асинхронной функции, а инициировать событие уже в колбеке, когда данные получены и их можно передать в обработчик события... |
Цитата:
Если бы ты смог сделать нормальный тестовый пример - на нем можно было бы показать варианты решений. |
Цитата:
|
Цитата:
К врачу (В) приходит пациент (П)... В - На что жалуетесь? П - Понимаете... Когда я делаю вот так (скручивается в неимоверную позу) - у меня начинает болеть вот тут! В - Не делайте так... |
Цитата:
global.X = ''; function A(){ с(); let z = global.X; //-- вот тут должно быть значение 'новая строка' } function B(){ d(); //--- инициализирует global.X let z = global.X; //-- вот тут должно быть значение 'новая строка' } async d(){ global.X = 'новая строка' ; } без вопросов - "а зачем"? расставляйте что надо сделать (только не поднимайте async до самого верха до функции A) |
Цитата:
function А(){ const res = myFnc() B(); //Точка 1 вот тут будешь использовать результаты асинхронной функции } async myFnc() { const res = await <та_самая_асанхронная_функция> return res } |
я привел пример. расставьте там
|
нужен же был нормальный тестовый пример?
поставьте на нем |
Цитата:
2. Там у тебя непонятка с функцией c() |
Цитата:
Каким боком тут B() ? |
с()
рассматривать как B() |
fxobject, вот, взял с твоего "текста" понятный кусок...
Цитата:
let X B() function B() { myFnc() alert(X) } async function myFnc() { return await d() } async function d() { X = 'новая строка' } |
Цитата:
let X A() function A(){ B(); alert('Это из A ' + X) } function B() { myFnc() alert('Это из B ' + X) } async function myFnc() { return await d() } async function d() { X = 'новая строка' } |
Цитата:
let X A() function A(){ B(); alert('Из A ' + X) } function B(){ d(); alert('Из B ' + X) } async function d(){ X = 'новая строка' ; } |
Цитата:
let X A() function A(){ B().then(res => alert('Из A ' + X)) } async function B(){ d().then(res => alert('Из B ' + X)); } async function d(){ X = 'новая строка' ; } |
Цитата:
|
Цитата:
|
Цитата:
Цитата:
|
Ну я понимаю, что бывают ситуации, когда очень нужно вызвать асинхронную функцию, дождаться результата и обработать его с верхнего уровня, где нельзя использовать await (вроде в последних Chrome и Node уже можно). Но ведь тогда так можно
;(async function () { let res = await asfunc (); // обрабатываем результат })(); |
Цитата:
const o = asfunc().then(res => o.emit('data', res)) o.on('data', (err, res) => alert(res)) |
подписку на события использую постоянно. вопрос технический. пытаюсь упорядочить представление о предмете.
Итак предложенный работающий вариант: let X A() function A(){ B(); alert('Это из A ' + X) } function B() { myFnc() alert('Это из B ' + X) } async function myFnc() { return await d() } async function d() { X = 'новая строка'} Действительно выдает правильный результат. Что внесло еще больше смятений..... потому как не должен. Внесем в него небольшие поправки.... давайте задержим выполнение функции MyFunc например так: async function myFnc() { let promise = new Promise((resolve,reject)=>{ setTimeout(()=>resolve("ok"),4000)}); let result = await promise; alert(result); return await d() } Вот так уже не работает...... |
задержку можно также перенести в функцию D. Она же асинхронная.... просто задержать ее. и все перестает работать
|
т.е. получается что если промис делает resolve или reject сразу. То мы получаем завершенный промис тоже сразу... и тогда приведенный пример действительно работает. Хотя не должен!
|
Цитата:
Я там тебе много вариантов выкладывал, а ты так и не научился делать нормальные примеры. :( |
Цитата:
|
Цитата:
|
Цитата:
И я тебе ничем не обязан. |
Понятно ))) А вчера кошек душили....... душили, душили .....)))))))
|
Часовой пояс GMT +3, время: 20:59. |