我目前正在将我的网页移到SPA(单页面应用程序),这样做我现在只使用一个html页面,使用JS填充(正常的SPA应该这样做)。因此,这意味着(为了方便起见)我将我的JS文件减少到一个(也许是一个好主意,也许是一个糟糕的 - 我们会看到,但这不是重点)。我决定制作一个黑盒子" AJAX请求处理程序,以便最小化代码。这是我遇到一个我没想到的问题。代码是(示例click
用于我的登录屏幕):
function ajaxCall(type, url, data, dataType) {
$.ajax({
type: type,
url: url,
data: data,
dataType: dataType,
})
.done(function(xhr) {
return xhr;
})
.fail(function(xhr, status, errorThrown) {
console.log('AJAX call error: ' + errorThrown);
console.dir(xhr);
})
.always(function(xhr, status) {
console.log('AJAX call status: ' + status);
});
}
var res;
//this is inside $(document).ready - I just skipped some lines
$(document).on('click', '#submit', function(e) {
res = ajaxCall('POST', '/Login', { 'username': $('#username').val(), 'password': $('#password').val() }, 'json');
console.log('res =', res); // this is where the problem was discovered
});
(有些人已经在呻吟)当然,当我测试这个时,我在控制台中得到的是res = undefined
。
我花了几个小时研究这个问题,并弄清楚它发生的原因。这些是我在尝试解决此问题时所研究的一些页面:1 2 3
切入追逐:问题是我没有使用Promise
。我明白了。我可以解决这个问题。我似乎无法修复的是使用带有jQuery AJAX请求的普通JS Promise
。
我已经走到了这一步:
function ajaxCall(type, url, data, dataType) {
return Promise.resolve($.ajax({
type: type,
url: url,
data: data,
dataType: dataType,
}));
}
但我无法弄清楚如何合并promise
的其他功能/功能,其中包括:.then() and .reject()
。据我了解,上述承诺将会自动解决,但如果需要拒绝怎么办?也许我还在想jQuery' .done(), .fail() and .always()
。
但是对于我的生活,尽管我做了所有谷歌搜索,我找不到如何将纯JS
Promise
的所有函数与jQuery AJAX请求完全合并。
因此,我要求stackoverflow社区深入了解这个问题。
谢谢。
答案 0 :(得分:2)
所以Promise
在这里并不是你的救世主。您遇到的问题是,在使用console.log('res =', res);
和.done()
方法完成AJAX请求后,您需要调用.fail()
。
function ajaxCall(type, url, data, dataType) {
return $.ajax({
type: type,
url: url,
data: data,
dataType: dataType,
});
}
//this is inside $(document).ready - I just skipped some lines
$(document).on('click', '#submit', function(e) {
var res = ajaxCall('POST', '/Login', { 'username': $('#username').val(), 'password': $('#password').val() }, 'json');
res.done(function (data) {
console.log('res =', data);
});
});
如果您真的想使用真实的Promise
,可以执行类似
function ajaxCall(type, url, data, dataType) {
return new Promise(function (resolve, reject) {
$.ajax({
type: type,
url: url,
data: data,
dataType: dataType,
}).done(function (data) {
resolve(data);
}).fail(function (jqXHR, textStatus, errorThrown) {
reject(errorThrown);
});
});
}
//this is inside $(document).ready - I just skipped some lines
$(document).on('click', '#submit', function(e) {
var res = ajaxCall('POST', '/Login', { 'username': $('#username').val(), 'password': $('#password').val() }, 'json');
res.then(function (data) {
console.log('res = ', data);
}).catch(function (err) {
console.error(err);
});
});