Promise .then() 不等待 Promise 链中前一个 Promise 的 Resolve()
Promise .then() Not Waiting For Resolve() Of the Previous Promise In A Promise Chain
我对 Promises 的概念很陌生,但我读到这是一种通过称为 Promise 链接的方式使函数一个接一个地执行的有效方法。
下面的 //运行 ON CLCK: CREATE TABLES 代码基本上进行了两次 AJAX 调用,“创建数据库表”和“检查数据库表”,因此当我按下按钮时网页,后台会创建数据库表,然后检查它们是否存在。
但它并不像预期的那样 运行。在许多情况下,从控制台日志中可以看出,第二个函数 运行s (or) 首先完成。无论如何,这不应该发生在链中。
看起来第二个函数没有等待第一个函数的解析。
请注意,我的函数有参数,因此我无法避免在 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()
,以便它稍后可以调用您的函数。相反,您立即调用这些函数并将它们的 return 值传递给 .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)});
});
我对 Promises 的概念很陌生,但我读到这是一种通过称为 Promise 链接的方式使函数一个接一个地执行的有效方法。
下面的 //运行 ON CLCK: CREATE TABLES 代码基本上进行了两次 AJAX 调用,“创建数据库表”和“检查数据库表”,因此当我按下按钮时网页,后台会创建数据库表,然后检查它们是否存在。
但它并不像预期的那样 运行。在许多情况下,从控制台日志中可以看出,第二个函数 运行s (or) 首先完成。无论如何,这不应该发生在链中。
看起来第二个函数没有等待第一个函数的解析。
请注意,我的函数有参数,因此我无法避免在 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()
,以便它稍后可以调用您的函数。相反,您立即调用这些函数并将它们的 return 值传递给 .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)});
});