Tengo un código similar a este:
$(function() { var focusOutEvent = function() { $.when( getCounterValue() ).done(function() { console.log('catchValidateButtonClick'); }); } var getCounterValue = function() { $.when( console.log('updateCacheData') ).done(function() { computeCounterValue(function() { console.log('counterValueComputation done'); }); }); } var computeCounterValue = function(callback) { setTimeout(function() { callback(); }, 3000); } focusOutEvent(); });
Actualmente, la consola imprime declaraciones en este orden:
¿Cómo hago para que la consola imprima "counterValueComputation done" antes de "catchValidateButtonClick"?
Haz getCounterValue
devuelva una Promesa. Aquí hay un ejemplo con cambios mínimos:
var getCounterValue = function() { return $.when( console.log('updateCacheData') ).then(function() { let d = $.Deferred(); computeCounterValue(function() { console.log('counterValueComputation done'); d.resolve(); }); return d; }); }
Aquí hay una forma más limpia de hacerlo:
var getCounterValue = function() { return $.when( console.log('updateCacheData') ).then(function() { return computeCounterValue().then(function() { console.log('counterValueComputation done'); }); }); } var computeCounterValue = function() { return new Promise(resolve => setTimeout(resolve, 3000)); }
Y así es como podría verse con async/await.
$(function() { var focusOutEvent = async function() { await getCounterValue(); console.log('catchValidateButtonClick'); } var getCounterValue = async function() { console.log('updateCacheData'); await computeCounterValue(); console.log('counterValueComputation done'); } var computeCounterValue = function() { return new Promise(resolve => setTimeout(resolve, 3000)); } focusOutEvent(); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>