Promise
简单来说,Promise主要就是为了解决异步回调的问题。用Promise来处理异步回调使得代码层次清晰,便于理解,且更加容易维护。
语法
new Promise( /* executor */ function(resolve, reject) { ... } );
参数:一个有两个参数为函数的函数,这个函数会立即执行。你可以在这个方法体中作异步操作,异步操作完成后,应调用resolve函数,Promise有三种状态:pending状态( 初始状态);fulfilled状态(操作完成时的状态);rejected状态(操作失败时的状态)【注意:Promise结束时会再次处于pending状态】 。fulfilled状态与resolve对应,rejected状态与reject对应,也就是异步操作失败后,应调用reject函数。
方法
p.then(onFulfilled[, onRejected]);
p.then(function(value) {
// fulfillment
}, function(reason) {
// rejection
});
参数:onFulfilled是一个函数,Promise完成时调用;onRejected是一个函数,Promise被拒绝即失败时调用。
p.catch(onRejected);
p.catch(function(reason) {
// rejection
});
参数:catch只有一个参数,也是个函数,Promise失败时调用。
详情请查阅:Promise MDN火狐官方开发文档
场景
我们需要使用XMLHttpRequest异步的方式向服务器发送请求来获取token值,然后,使用XMLHttpRequest异步地将获取的token和必要的数据发送到服务器。
这是一个异步嵌套异步的结构。我们将通过Promise对象去实现异步控制。
代码
let saveToServer = function(sJson) {
//获取token
let oPromise = new Promise(function(success, error){
let oXhr = new XMLHttpRequest();
let sUrl = "/getCsrf.html";
oXhr.open("get", sUrl, true);
oXhr.send(null);
oXhr.onreadystatechange = function() {
if(oXhr.readyState == 4) {
if(oXhr.status == 200) {
//oXhr.responseText:"<input type="text" name="${_csrf.parameterName}" value="${_csrf.token}">"
let sInput = oXhr.responseText;
let eInput = {};
//将sInput转为eInput
let eDiv = document.createElement("div");
eDiv.innerHTML = sInput;
if(eDiv.childNodes.length > 0){
eInput = eDiv.childNodes[0];
let sToken = eInput.value;
let sName = eInput.getAttribute("name");
success({sName: sName, sValue: sToken});
}else{
error(oXhr.responseText);
}
}
else
Console.error("saveToServer(): Fail to get _token from server: " + oXhr.status);
}
}
});
//token获取成功,发送打标词组
oPromise.then(function(jToken){
let oXhr = new XMLHttpRequest();
let sUrl = "saveAnnotate.html?"+ jToken.sName + "=" + jToken.sValue;
oXhr.open("post", sUrl, true);
oXhr.send(sJson);
oXhr.onreadystatechange = function() {
if(oXhr.readyState == 4) {
if(oXhr.status == 200) {
let sMsg = oXhr.responseText.trim();
Console.debug("saveToServer(): response is " + sMsg);
if (sMsg.indexOf("success") >= 0) {
…… ……
}
else {
alert("失败!");
}
}
else
Console.error("saveToServer(): Fail to communicate with server: " + oXhr.status);
}
}
});
//token获取失败
oPromise.catch(function(sMsg){
Console.error("saveToServer(): token format error: " + sMsg);
});
}