Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   async/await как получить вернуть значение из функции (https://javascript.ru/forum/events/79861-async-await-kak-poluchit-vernut-znachenie-iz-funkcii.html)

dpts 02.04.2020 07:36

async/await как получить вернуть значение из функции
 
Доброго дня.
Может кто-нибудь внятно объяснить следующее
В учебнике https://learn.javascript.ru/async-await
Есть такой пример:
async function f() {

  let promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve("готово!"), 1000)
  });

  let result = await promise; // будет ждать, пока промис не выполнится (*)

  alert(result); // "готово!"
}

f();


Все отлично, все работает. alert с текстом Готово выводится.
Если вот этот место
alert(result); // "готово!"
}

f();

переписать, как
return result;
}
alert(f());

Получаем ObjectPromice.

И ни один пример на странице внятно не объясняет как из функции вернуть "готово!".

Вот и вопрос. как в alert(f()) "получить" - "готово!"?

voraa 02.04.2020 08:00

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

return value в async функции эквивалентно return Promise.resolve(value), если value не является Promise. А если value - Promise, то оно и возвращается.

Что бы достать значение из возвращенного Promise - используется оператор await

async function f () {return 42}

let a = f() // a = Promise.resolve(42)
let b = await f() // b = 42

Поэтому переписываем alert (await f())

dpts 02.04.2020 08:39

Цитата:

Сообщение от voraa (Сообщение 522105)
...
Поэтому переписываем alert (await f())

alert (await f()) говорит: "Uncaught SyntaxError: missing ) after argument list"

voraa 02.04.2020 09:03

Есть тут особенность. Оператор await можно использовать только внутри асинхронных функций.
Поэтому надо обернуть код в асинхронную функцию, а потом вызывать ее

async function main () {
	async function f() {

	  let promise = new Promise((resolve, reject) => {
		setTimeout(() => resolve("готово!"), 1000)
	  });

	 return promise; // будет ждать, пока промис не выполнится (*)

	  
	}

	alert( await f());

}

main()


Другой вариант - просто использовать then

async function f() {

	  let promise = new Promise((resolve, reject) => {
		setTimeout(() => resolve("готово!"), 1000)
	  });

	 return promise; // будет ждать, пока промис не выполнится (*)

	  
	}

	f().then (res => alert(res))

dpts 02.04.2020 09:22

Цитата:

Сообщение от voraa (Сообщение 522112)
Есть тут особенность. Оператор await можно использовать только внутри асинхронных функций.
Поэтому надо обернуть код в асинхронную функцию, а потом вызывать ее

async function main () {
	async function f() {

	  let promise = new Promise((resolve, reject) => {
		setTimeout(() => resolve("готово!"), 1000)
	  });

	 return promise; // будет ждать, пока промис не выполнится (*)

	  
	}

	alert( await f());

}

main()


Другой вариант - просто использовать then

async function f() {

	  let promise = new Promise((resolve, reject) => {
		setTimeout(() => resolve("готово!"), 1000)
	  });

	 return promise; // будет ждать, пока промис не выполнится (*)

	  
	}

	f().then (res => alert(res))

Я, конечно сам виноват. Не совсем корректно задал вопрос.
По большому-то счету нет задачи вывести алертом "готово", задача var i = f(), с тем, чтобы в i оказалось готово.

voraa 02.04.2020 09:31

Цитата:

Сообщение от dpts (Сообщение 522113)
Я, конечно сам виноват. Не совсем корректно задал вопрос.
По большому-то счету нет задачи вывести алертом "готово", задача var i = f(), с тем, чтобы в i оказалось готово.

Если этот самый var i находится в какой то функции, то придется делать ее асинхронной и писать

var i = await f();

Иначе

var i;
f().then(res => i = res);

В Javascript нет способа заставить код просто ждать, когда что то произойдет. Есть только возможность, сказать; "Когда произойдет, сделай то то."
Но код при этом будет выполняться дальше

dpts 02.04.2020 09:54

Цитата:

Сообщение от voraa (Сообщение 522114)
...
var i;
f().then(res => i = res);

В Javascript нет способа заставить код просто ждать, когда что то произойдет. Есть только возможность, сказать; "Когда произойдет, сделай то то."
Но код при этом будет выполняться дальше

Благодарю. Теперь более-менее понятно.

voraa 02.04.2020 09:56

Цитата:

Сообщение от voraa (Сообщение 522114)
Если этот самый var i находится в какой то функции, то придется делать ее асинхронной и писать

var i = await f();

Иначе

var i;
f().then(res => i = res);

Я не совсем корректно описал
Допустим есть
async function f () {....return val}

async function g() {

  var i = await f()
// какие то другие операторы
  var j = 3*i  // j зависит от i
// еще операторы

}

Тогда это будет эквивалентно (Интерпретатор буквально преобразует код)
async function g() {
  var i; 
  f().then ( res => {
     i = res;
    // какие то другие операторы
     var j = 3*i  // j зависит от i
    // еще операторы
 })
}


Часовой пояс GMT +3, время: 13:11.