Estou fazendo alguns testes de unidade. A estrutura de teste carrega uma página em um iframe e, em seguida, executa asserções nessa página. Antes de cada teste começar, eu crio um Promise
que define o onload
evento do iframe para chamar resolve()
, define o do iframe src
e retorna a promessa.
Então, eu posso apenas ligar loadUrl(url).then(myFunc)
e ele vai esperar a página carregar antes de executar o que quer que myFunc
seja.
Eu uso esse tipo de padrão em todos os lugares em meus testes (não apenas para carregar URLs), principalmente para permitir que mudanças no DOM aconteçam (por exemplo, imitar clicar em um botão e esperar que divs sejam ocultados e exibidos).
A desvantagem desse design é que estou constantemente escrevendo funções anônimas com algumas linhas de código. Além disso, enquanto eu tenho uma solução alternativa (QUnit'sassert.async()
), a função de teste que define as promessas é concluída antes que a promessa seja executada.
Estou me perguntando se existe alguma maneira de obter um valor de a Promise
ou esperar (bloquear / suspender) até que seja resolvido, semelhante ao do .NET IAsyncResult.WaitHandle.WaitOne()
. Eu sei que o JavaScript é de thread único, mas espero que isso não signifique que uma função não possa produzir.
Em essência, existe uma maneira de fazer com que o seguinte mostre os resultados na ordem correta?
function kickOff() {
return new Promise(function(resolve, reject) {
$("#output").append("start");
setTimeout(function() {
resolve();
}, 1000);
}).then(function() {
$("#output").append(" middle");
return " end";
});
};
function getResultFrom(promise) {
// todo
return " end";
}
var promise = kickOff();
var result = getResultFrom(promise);
$("#output").append(result);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="output"></div>
.then(fnAppend.bind(myDiv))
, que podem reduzir enormemente os anons.