В следующем коде:
function getPosition() {
return new Promise((res, rej) => {
navigator.geolocation.getCurrentPosition(res, rej);
});
}
function main() {
getPosition().then(console.info);
}
main();
Я могу зарегистрировать объект Position в браузере. Но что, если вместо регистрации я хочу вернуть это значение, чтобы его можно было использовать вне then (). Это возможно?
Я пробовал следующее:
function main() {
return getPosition().then();
}
console.info(main());
Но вместо того, чтобы просматривать мой объект Position в журнале, я вижу следующее:
Promise {<pending>}
__proto__: Promise
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: Position
Это тоже не работает
function main() {
getPosition().then(function(response){
return response;
});
}
console.info(main());
У меня в журнале есть неопределенный.
Возможный дубликат Как мне вернуть ответ от асинхронного вызова?
Обещание для управления async
с кодом developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
@ imans77 Просто попробовал, но все равно не определено
он асинхронный, поэтому обещание будет разрешено после выполнения функции main
. Добавьте оператор возврата в main
и напишите main().then(console.info)
Все, что нужно сделать OP, - это добавить async
перед функцией main
, поместить await
перед вызовом функции main
и вырезать 90% кода в main
. OP четко спросил> Я хочу, чтобы это значение возвращение можно было использовать за пределами тогдашнего. Это ТОЧНО, что такое async / await. Невероятно, что пользователи отводят OP, а не новичка в Javascript, от этого решения.
"чтобы его можно было использовать вне then ()" ... где и когда именно вы хотите его использовать? Promise является асинхронным, поэтому вы можете использовать его только после того, как обещание будет выполнено. Ваши варианты: либо выполнить любую функциональность, требующую значения из вызова then (), либо присвоить значение глобальной переменной, которая затем сохраняется для дальнейшего использования (например, когда происходит какое-либо другое событие).
Или очень просто вы можете вернуть Promise из main () и переместить местоположение then ... например. функция main () {return getPosition (); } main (). then (функция (ответ) {console.info (ответ)}); `. Не забывайте, что вы можете определить столько функций then (), done () или fail () в Promise, сколько захотите, вы не ограничены одним. Или, как было предложено выше, вы можете использовать await, чтобы снова сделать все синхронным, но это блокирует основной поток и как бы устраняет весь смысл использования обещаний и асинхронных операций.
Вы можете использовать async / await
async function main() {
console.info(await getPosition());
}
Вот рабочий фрагмент, демонстрирующий это:
function getPosition() {
return new Promise((res, rej) => {
// simulate API
setTimeout( ()=> res('123,456'), 1000)
});
}
async function main(){
console.info(await getPosition())
}
main()
Я думаю, он не понимал концепции Promise и концепции кода async
. Кстати, использование await
будет еще большим источником неприятностей, так как это способ или запись кода async
способом synchronous
?
Если OP хочет кодировать в стиле получения значения за пределами then
, им необходимо понимать понятие async / await.
Вы не можете использовать ожидание вне функции async
@slebetman Я обновил ответ. Это ясно демонстрирует то, о чем просил ОП.
не рекомендуется все смешивать, я думаю, что OP должен сначала понять, как работает Promise, прежде чем использовать async await
(который за сценой использует генератор es6)
@ OlivierBoissé Я не согласен. В конце концов, они такие же. async / await легче читать / писать / отлаживать. Я слышал этот аргумент раньше. OP должен понимать концепцию асинхронных функций обратного вызова, независимо от синтаксиса then
или async / await. Кроме того, наличие функций, помеченных как асинхронные, дает понять, что они являются асинхронными.
Обещание предназначено для обработки операций async
(подумайте о вызовах ajax или коде, выполняемом внутри setTimeout
), поэтому у вас не может быть чего-то вроде этого
console.info(getPosition().then())
вам нужно передать обратный вызов методу then
, этот обратный вызов будет выполнен, когда обещанное будет разрешено (подумайте об успешном обратном вызове в jquery
)
Итак, в основном в вашем примере у вас будет что-то вроде этого:
function main() {
return getPosition();
}
main().then(console.info);
вы также можете сохранить обещание в переменной, чтобы использовать его где-нибудь еще в вашем коде
var position = main();
position.then(console.info);
position.then(console.info);
position.then(positionValue => {/* do what you want with the value */});
Обратите внимание, что вызов then
несколько раз не приведет к многократному выполнению обещания, он будет разрешен только один раз.
да, но допустим, я хочу сохранить значение, возвращаемое моей основной функцией, в переменной, которая будет использоваться в какой-то момент кода, как мне это сделать вместо того, чтобы просто войти в console.info?
Если я попытаюсь установить значение переменной в обратном вызове .then (function (response) {myvar = response}); и пытаюсь использовать myvar вне этого, я все равно получаю undefined
затем сохраните promise
вместо окончательного значения var promise = main()
, каждый раз, когда вам понадобится значение, которое вы вызываете promise.then(() => ....)
Не могли бы вы обновить свой ответ предложениями из вашего последнего комментария, пожалуйста
@ user765368 только что сделал это
Спасибо, подождите, мне нужно использовать console.info?
console.info
- это просто пример, это ярлык для positionValue => console.info(positionValue)
, вы можете определить свой собственный обратный вызов
Вам нужно поместить весь другой код, который хочет использовать значение, внутри then()
. console.info
- не единственное, что можно использовать в обратном вызове
поставьте
return
заnavigator...
и заменитеreturn response
наreturn Promise.resolve(response)