javascript - 如何添加承诺以使 $.when 和 .then 正常运行?
问题描述
我遇到了由异步 Javascript 执行引起的问题。我正在尝试使用函数设置变量的值,然后立即在函数调用中使用该变量。我想实现 JQuery .when 和 .then 来解决这个问题,但是我在如何实现 .then 知道何时开始执行所需的承诺方面遇到了麻烦。
这是我所拥有的:
function addSerialNumber(item_id) {
var serialNumberList;
var serialNumber = $("serial-number").val();
$.when(serialNumberList = addSerialFunc(item_id, serialNumber))
.then(alert("Serial number successfully added."),
insertTransaction(item_id, serialNumberList));
}
function addSerialFunc(item_id, serialNumber) {
var serialNumberList = new Array();
$.ajax({
type: "post",
url: "someRandom.jsp",
data: {wsFunction: "Insert", item_id: item_id, serialNumber: serialNumber},
async: false
}).done(function(xml){
$(xml).find("Item").each(function() {
insert_id = ($(this).find("SendBack_CD").text());
if (!runError(insert_id, item_id)) {
//Fail
} else {
//Success
serialNumberList.push(insert_id);
}
})
}).fail(function(jqXHR, textStatus, errorThrown) {
console.log("Error occured! Type: " + textStatus + " HTTP Error Thrown: " + errorThrown);
});
return serialNumberList;
}
我正在尝试通过调用 addSerialFunc() 创建 serialNumberList,然后使用 serialNumberList 作为 insertTransaction() 的参数。这有时有效,但我间歇性地得到
Uncaught TypeError: Cannot read property 'substring' of undefined
因为它试图在 addSerialFunc() 填充 serialNumberList 之前执行 insertTransaction()。
如何在 addSerialFunc() 中实现承诺,以便 .then 知道何时开始执行?
解决方案
几个问题:
在
addSerialFunc
您同步返回一个值,但它只会在以后填充,当响应来自异步 ajax 调用时。相反,您应该返回由$.ajax
.您
alert
立即调用,而不是将回调函数传递给then
.您将第二个参数传递给
then
,由于与前一点相同的原因,这又不是一个函数。而且,第二个参数应该是当 Promise 被拒绝时的函数。
所以,这应该会更好——它假设 jQuery 版本 3.x:
function addSerialNumber(item_id) {
var serialNumberList;
var serialNumber = $("serial-number").val();
// *** $.when is not needed
addSerialFunc(item_id, serialNumber) // *** start with the returned promise
.then(function (serialNumberList) { // pass a function(!), which gets the value as argument
alert("Serial number successfully added.");
insertTransaction(item_id, serialNumberList);
}).catch(function (err) { // better to also have a `catch` call here
console.log(err);
console.log("because of error, no transaction is inserted");
});
}
function addSerialFunc(item_id, serialNumber) {
return $.ajax({
// ^^^^^^
type: "post",
url: "someRandom.jsp",
data: {wsFunction: "Insert", item_id: item_id, serialNumber: serialNumber}
/* drop the `async` property */
}).then(function(xml){
// ^^^^
var serialNumberList = new Array(); // *** define here
$(xml).find("Item").each(function() {
var insert_id = ($(this).find("SendBack_CD").text());
// ^^^^ make sure to always define the scope of your variables!
if (!runError(insert_id, item_id)) {
//Fail
throw "Some error occurred"; // *** adapt message here
^^^^^^
} else {
//Success
serialNumberList.push(insert_id);
}
});
return serialNumberList; // *** return!!!!
}).catch(function(jqXHR, textStatus, errorThrown) {
// ^^^^^
console.log("Error occured! Type: " + textStatus + " HTTP Error Thrown: " + errorThrown);
throw errorThrown; // *** cascade the error
});
}
推荐阅读
- python - 尝试将数据从表单传递到 Django 中的数据库时出现 NoReverseMatch 错误
- c++ - 优化:Hackerearth Postman 软件工程师实习生问题
- c++ - 关于 *p 和 for 循环中的 p 的问题
- html - 隐藏正文溢出时启用组件中的滚动(角度 8)
- javascript - 如何在 JavaScript 中包含 ejs 部分?
- azure - 使用 PowerShell 将特定 Azure AD 组的成员作为所有者同步到所有其他 AD 组
- sql - 在 Postgres 中使用条件 where 子句更新多行?
- javascript - 如何理解包含驻留在我网站上的 javascript 的页面的域?
- javascript - Chrome 扩展不安全内联
- java - 相同的代码适用于一个项目,但不适用于其他项目。错误是 NullPointerException 但我在使用它之前创建了对象