我有一些代码,我想在一个函数完成后执行它,并且点击一个按钮就会调用这组步骤和函数。以下是我的代码:
$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')
。这里的实际问题是什么?我不太确定承诺在这里的运作方式!任何人都可以告诉你如何纠正这个问题吗?
答案 0 :(得分:3)
$.when()
无法正常工作,因为您没有从您传递的功能中返回承诺。但是,showLoader()
不是异步的,因此根本不需要使用它。
由于您的代码中没有显示异步操作,您可以像这样同步编程:
$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()
返回承诺。showLoader()
完成后,您必须解决该承诺。$.when()
。 $.when()
通过传递一个或多个promises来处理异步操作,然后监视这些promises何时得到解决,并且只有当你传递的所有promise都已解决时才解决它自己的承诺。< / p>
由于现在看来您要解决的实际问题是如何在其他代码运行之前强制重新绘制,您可以在此答案中看到如何执行此操作:When does the DOM repaint during Javascript routines?