Estoy tratando de deshabilitar el botón hasta que el código se ejecute con éxito. Desafortunadamente, el botón se activó demasiado pronto, la función aún se está ejecutando. ¿Cómo puedo prevenir esto?
$("#myButton").click(function() { $(this).prop("disabled", true) doSomethingFunction() $(this).prop("disabled", false) });Editar: Gracias a todos por su ayuda. He ajustado mi código. ¿Puedes hacerlo de esta manera o hay mejores formas?
class TestClass { static doSomethingFunction() { return new Promise(function (resolve, reject) { setTimeout(function () { console.log("function is done"); resolve(self); }, 5000); }) } } $("#myButton").click(function() { $(this).prop("disabled", true) TestClass.doSomethingFunction().then(r => $(this).prop("disabled", false)) });La segunda solución no funciona para mí, porque se muestra "completamente hecho" antes de "terminar la función"
class TestClass { static doSomethingFunction(callback) { setTimeout(function () { console.log("function is done");}, 2000); if(callback !== undefined){ callback(); } } } $("#myButton").click(function() { $(this).prop("disabled", true) TestClass.doSomethingFunction(function(){ console.log("completely done") }); });¿Qué estoy haciendo mal?
Considera lo siguiente.
var myData; function doSomethingFunction(callback){ $.get("someplace.php", function(data){ myData = data; if(callback !== undefined){ callback(); } }); } $("#myButton").click(function() { var $self = $(this); $self.prop("disabled", true); doSomethingFunction(function(){ console.log(myData); $self.prop("disabled", false); }); });Esto le permite pasar el código para que se ejecute una vez que se completa la función. En este ejemplo, tal vez esté obteniendo datos del servidor. Esto puede llevar casi nada de tiempo, o tal vez el informe tarde 1,2 segundos en generarse. De cualquier manera, no se ejecutará hasta que AJAX sea exitoso.
Actualizar
Aquí hay un ejemplo, basado en lo siguiente: ¿Cómo uso jQuery promise/deffered en una función personalizada?
$(function() { function doSomething() { var deferred = new $.Deferred(); setTimeout(function() { deferred.resolve(10); }, 10 * 1000); return deferred; } $("button").click(function() { var $self = $(this); console.log("Disabled"); $self.prop("disabled", true); doSomething().then(function() { $self.prop("disabled", false); console.log("Enabled"); }); }); }); <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <button>Start</button>Esto se ejecutará durante 10 segundos y luego habilitará el botón. Aplicándolo a tu ejemplo.
class TestClass { static doSomethingFunction() { var deferred = new $.Deferred(); setTimeout(function() { deferred.resolve(10); }, 5 * 1000); return deferred; } } $("#myButton").click(function() { var $self = $(this); $self.prop("disabled", true); TestClass.doSomethingFunction().then(r => $self.prop("disabled", false)); });