我有一些代码,我想在函数完成后执行这些代码,并且单击按钮即可调用这组步骤和函数。下面是我的代码:
$scope.activetab = function (tabname, $event) {
$.when(function () {
showLoader();
alert('done');
}).done(function () {
alert('next');
if (tabname == 'General')
$scope.GeneralAct = true;
else if (tabname == 'Contact Information')
$scope.ContactAct = true;
else if (tabname == 'Position/Hierarchy')
$scope.PositionAct = true;
else if (tabname == 'Ids and Program Access')
$scope.IdsAct = true;
else if (tabname == 'Equipment')
$scope.EquipmentAct = true;
else if (tabname == 'Licensing')
$scope.LicensingAct = true;
});
};
我的showLoader
函数如下:
function showLoader() {
var dfd = $.Deferred();
$('body').append('<div class="loader"></div>');
dfd.promise();
}
但是这里先执行alert('next')
,然后执行alert('done')
。这里的实际问题是什么?我不太确定这里的 promise 是如何运作的!谁能告诉我如何纠正这个问题吗?
最佳答案
$.when()
无法正常工作,因为您没有从传递它的函数返回 promise 。但是,showLoader() 不是异步的,因此根本不需要使用 Promise。
由于代码中没有显示异步操作,因此您可以像这样同步编程:
$scope.activetab = function (tabname, $event) {
showLoader();
if (tabname == 'General')
$scope.GeneralAct = true;
else if (tabname == 'Contact Information')
$scope.ContactAct = true;
else if (tabname == 'Position/Hierarchy')
$scope.PositionAct = true;
else if (tabname == 'Ids and Program Access')
$scope.IdsAct = true;
else if (tabname == 'Equipment')
$scope.EquipmentAct = true;
else if (tabname == 'Licensing')
$scope.LicensingAct = true;
};
function showLoader() {
// this is a synchronous operation, so no need for promises here
$('body').append('<div class="loader"></div>');
}
如果 showLoader()
内部有一个异步操作,那么要将其与 $.when()
一起使用,您必须做三件事目前没有在做:
- 您必须从
showLoader()
返回一个 Promise。 - 当
showLoader()
完成时,您必须解决该 promise 。 - 您必须将该 Promise 传递给
$.when()
。
$.when()
通过向其传递一个或多个 Promise 来处理异步操作,然后它会监视这些 Promise 何时得到解决,并且仅当您传递给它的所有 Promise 都已得到解决时,它才会解决它自己的 Promise。已解决。
既然现在看来您想要解决的真正问题是如何在其他代码运行之前强制重新绘制,您可以在这个答案中看到如何做到这一点:When does the DOM repaint during Javascript routines?
关于javascript - 处理 jquery Promise 时函数序列未按预期执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30453428/