Это очень распространенная проблема, с которой мы сталкиваемся, борясь с «таинствами» JavaScript.
Давайте начнем с простой функции JavaScript:
function foo(){
// do something
return 'wohoo';
}
let bar = foo(); // bar is 'wohoo' here
Это простой синхронный вызов функции (где каждая строка кода выполняется одна за другой в последовательность), и результат будет таким же, как ожидалось.
Теперь добавим немного завихрения, введя небольшую задержку в нашей функции, чтобы все строки кода не выполнялись последовательно. Таким образом, он будет эмулировать асинхронное поведение функции:
function foo(){
setTimeout( ()=>{
return 'wohoo';
}, 1000 )
}
let bar = foo() // bar is undefined here
Итак, вы идете, эта задержка просто сломала функциональность, которую мы ожидали! Но что именно произошло? Ну, на самом деле это довольно логично, если вы посмотрите на код. функция foo()
после выполнения ничего не возвращает (таким образом, возвращаемое значение равно undefined
), но оно запускает таймер, который выполняет функцию после 1s, чтобы вернуть «wohoo». Но, как вы можете видеть, значение, присвоенное бару, является немедленно возвращенным материалом из foo (), а не что-либо еще, что приходит позже.
Итак, как мы решаем эту проблему?
Давайте попросим нашу функцию для ОБЕЩАНИЯ. Обещание действительно о том, что это означает: это означает, что функция гарантирует, что вы предоставите любой результат, который он получит в будущем. поэтому давайте посмотрим на это в нашей маленькой проблеме выше:
function foo(){
return new Promise( (resolve, reject) => { // I want foo() to PROMISE me something
setTimeout ( function(){
// promise is RESOLVED , when exececution reaches this line of code
resolve('wohoo')// After 1 second, RESOLVE the promise with value 'wohoo'
}, 1000 )
})
}
let bar ;
foo().then( res => {
bar = res;
console.log(bar) // will print 'wohoo'
});
Таким образом, резюме - для решения асинхронных функций, таких как вызовы на основе ajax и т. д., вы можете использовать обещание resolve
значение (которое вы намерены вернуть). Таким образом, короче говоря, вы разрешаете значение вместо возврата в асинхронных функциях.
Действительно, JSF как платформа, ориентированная на форму, ориентированная на MVC, передает форму POST на тот же URL-адрес, где запрашивается страница с <h:form>
. Вы можете подтвердить это, посмотрев URL <form action>
сгенерированного вывода HTML. Это в терминах веб-разработки, охарактеризованных как postback . Навигация по обратной передаче по умолчанию не вызывает новый запрос к новому URL-адресу, но вместо этого загружает целевую страницу в качестве содержимого ответа. Это действительно сбивает с толку, когда вы просто хотите навигация по страницам.
Как правило, правильный подход к навигации / перенаправлению зависит от бизнес-требований и idempotence (читайте: «bookmarkability») запроса.
<form>
, <h:link>
или <h:button>
из <h:form>
и <h:commandXxx>
). Например, навигация по страницам, формам поиска в Google и т. Д. null
или void
и использовать, например, <h:message(s)>
и / или rendered
). Например, ввод / редактирование данных, многошаговый мастер, модальный диалог, форма подтверждения и т. Д. ?faces-redirect=true
или <redirect/>
). Например, показывая список всех данных после успешного редактирования, перенаправляя после входа в систему и т. Д. Обратите внимание, что чистая навигация по страницам обычно является идемпотентной, и именно здесь многие неудачники JSF терпят неудачу злоупотребляя командами / кнопками для этого, а затем жаловаться после этого, что URL-адреса не изменяются. Также обратите внимание, что навигационные случаи очень редко используются в приложениях реального мира, которые разрабатываются в отношении SEO / UX, и это приводит к тому, что многие учебники JSF терпят неудачу, позволяя читателям поверить иначе.
Также обратите внимание, что использование POST абсолютно не «более безопасно», чем GET, поскольку параметры запроса не отображаются сразу в URL-адресе. Они все еще видны в теле запроса HTTP и все еще манипулируются. Поэтому нет абсолютно никаких оснований предпочитать POST для идемпотентных запросов ради «безопасности». Реальная безопасность заключается в использовании HTTPS вместо HTTP и проверке методов бизнес-обслуживания, если в настоящее время зарегистрированный пользователь может запрашивать объект X или манипулировать объектом X и т. Д. Применимая система безопасности предлагает аннотации для этого.