我对Promises的概念很陌生,但我读到这是一种通过执行Promise链接来让函数一个接一个地执行的有效方法。
下面的//RUN ON CLCK:CREATE TABLES代码基本上进行了两个AJAX调用;创建数据库表";以及";检查数据库表";,这样,当我按下网页上的按钮时,数据库表将在后端创建,然后检查它们的存在。
但它并没有按预期运行。在许多情况下,从控制台日志中可以看出,第二个函数首先运行(或(完成。无论如何,这不应该发生在一个链条上。
第二个函数似乎没有等待第一个函数的解析。
请注意,我的函数有参数,所以我无法避免像其他文章建议的那样,在then((中没有括号的情况下调用它们。
$(document).ready(function() {
/*PAGE VARS*/
var mainAdmStgChkTblSrvltMsg_elm = document.getElementById('mainAdmStgChkTblSrvltMsg');
var mainAdmStgCrDelTblSrvltMsg_elm = document.getElementById('mainAdmStgCrDelTblSrvltMsg');
var mainAdmStgCrTblBtn_elm = document.getElementById('mainAdmStgCrTblBtn');
/*FN DEF: CHECK TABLES*/
var chkTbl = function(tblNm) {
return new Promise(function(resolve, reject) {
$.ajax({
type: 'GET',
url: '../../../../../../app/TblSrvlt',
data: {
getType: 'chkTbl',
tblNm: tblNm
},
success: function(data) {
var srvltMsg = data.srvltMsg;
var srvltSuccess = data.srvltSuccess;
mainAdmStgChkTblSrvltMsg_elm.textContent = srvltMsg;
if (srvltSuccess === true) {
mainAdmStgChkTblSrvltMsg_elm.setAttribute('class', 'text-success');
} else {
mainAdmStgChkTblSrvltMsg_elm.setAttribute('class', 'text-danger');
}
/*RETURN RESOLVE FOR PROMISE CHAIN*/
console.log("chkTbl");
resolve();
}
});
});
};
/*FN DEF: CREATE TABLES*/
var crTbl = function(tblNm) {
return new Promise(function(resolve, reject) {
$.ajax({
type: 'POST',
url: '../../../../../../app/TblSrvlt',
data: {
postType: 'crTbl',
tblNm: tblNm
},
success: function(data) {
var srvltMsg = data.srvltMsg;
var srvltSuccess = data.srvltSuccess;
mainAdmStgCrDelTblSrvltMsg_elm.textContent = srvltMsg;
if (srvltSuccess === true) {
mainAdmStgCrDelTblSrvltMsg_elm.setAttribute('class', 'text-success');
} else {
mainAdmStgCrDelTblSrvltMsg_elm.setAttribute('class', 'text-danger');
}
/*RETURN RESOLVE FOR PROMISE CHAIN*/
console.log("crTbl");
resolve();
}
});
});
};
/*RUN ON CLCK: CREATE TABLES*/
$(document).on('click', '#' + mainAdmStgCrTblBtn_elm.id, function() {
Promise.resolve()
.then(crTbl("chairs"))
.then(chkTbl("chairs"))
.catch();
});
});
您必须将函数引用传递给.then()
,这样它才能调用您的函数LATER。相反,您将立即调用这些函数,并将它们的返回值传递给.then()
,这就是为什么它们将立即被调用,而不是等待先前的承诺得到解决。
更改此项:
/*RUN ON CLCK: CREATE TABLES*/
$(document).on('click', '#' + mainAdmStgCrTblBtn_elm.id, function() {
Promise.resolve()
.then(crTbl("chairs"))
.then(chkTbl("chairs"))
.catch();
});
到此:
/*RUN ON CLCK: CREATE TABLES*/
$(document).on('click', '#' + mainAdmStgCrTblBtn_elm.id, function() {
Promise.resolve()
.then(function() {return crTbl("chairs")})
.then(function() {return chkTbl("chairs")})
.catch(function(err) { console.log(err)});
});
而且,实际上在链的开头并不需要Promise.resolve()
:
/*RUN ON CLCK: CREATE TABLES*/
$(document).on('click', '#' + mainAdmStgCrTblBtn_elm.id, function() {
crTbl("chairs")
.then(function() {return chkTbl("chairs")})
.catch(function(err) { console.log(err)});
});