文章目录
文章参考
基本语法
早期浏览器兼容:Promise对象是ES6的内容,我们可以使用babel做一个转换,基本语法如下:
var promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
//then方法的第一个参数是resolved状态的回调函数,第二个参数(可选)是rejected状态的回调函数。
promise.then(function funcA(comments) {
console.log("resolved: ", comments);
}, function funcB(err){
console.log("rejected: ", err);
});
捕获异常处理
var promise = new Promise(function(resolve, reject) {
throw new Error('test');
});
promise.catch(function(error) {
console.log(error);
});
链式调用
参考 https://segmentfault.com/a/1190000007598894
参考 http://es6.ruanyifeng.com/#docs/promise#Promise-prototype-then
采用链式的then,可以指定一组按照次序调用的回调函数。这时,前一个回调函数,有可能返回的还是一个Promise对象(即有异步操作),这时后一个回调函数,就会等待该Promise对象的状态发生变化,才会被调用。
function start() {
return new Promise((resolve, reject) => {
resolve('start');
});
}
start()
.then(data => {
// promise start
console.log('result of start: ', data);
return Promise.resolve(1); // p1
})
.then(data => {
// promise p1
console.log('result of p1: ', data);
return Promise.reject(2); // p2
})
.then(data => {
// promise p2
console.log('result of p2: ', data);
return Promise.resolve(3); // p3
})
.catch(ex => {
// promise p3
console.log('ex: ', ex);
return Promise.resolve(4); // p4
})
.then(data => {
// promise p4
console.log('result of p4: ', data);
});
上面的代码最终会输出:
result of start: start
result of p1: 1
ex: 2
result of p4: 4
promise的finally方法
应用场景
在做移动app开发的时候,需要每次发送请求,都会有‘菊花’提示,请求发送完毕,就需要关闭loading提示框,不然界面就无法被点击
。但是请求有的是成功、有的失败、有的超时,为了不影响整个系统的正常使用,就需要强制关闭提示框,正好利用promise的finally来关闭提示框
var promise = new Promise(function(resolve, reject) {
console.log("promise")
window.setTimeout(function(){
if (false){
resolve('huangbiao');
} else {
debugger
reject('error');
}
},1000)
}).then(function(){
console.log('success');
}).catch(function(){
console.log('catch');
}).finally(function(){
console.log('finally');
});
不管promise最后的状态,在执行完then或catch指定的回调函数以后,都会执行finally方法指定的回调函数。
异步应用场景使用说明
两个请求没有必然关系,各自执行回调即可
var promiseOne = axios.get('http://first').then(function(resOne) {
// 请求One 成功之后的回调,
// 根据返回的数据调用 setState(resOne)就可以将返回的数据在浏览器中显示
})
var promiseTwo = axios.get('http://second').then(function(resTwo) {
// 请求Two 成功之后的回调
// 根据返回的数据调用 setState(resTwo)就可以将返回的数据在浏览器中显示
})
两个请求有先后顺序,一定要先请求One之后再用Two
var promiseOne = axios.get('http://first').then(function(resOne) {
// 请求One 成功之后的回调,
// 根据返回的数据调用 setState(resOne)就可以将返回的数据在浏览器中显示
var promiseTwo = axios.get('http://second').then(function(resTwo) {
// 请求Two 成功之后的回调
// 根据返回的数据调用 setState(resTwo)就可以将返回的数据在浏览器中显示
})
})
var promiseTwo = axios.get('http://second').then(function(resTwo) {
// 请求Two 成功之后的回调
// 根据返回的数据调用 setState(resTwo)就可以将返回的数据在浏览器中显示
var promiseOne = axios.get('http://first').then(function(resOne) {
// 请求One 成功之后的回调,
// 根据返回的数据调用 setState(resOne)就可以将返回的数据在浏览器中显示
setState(resTwo+resOne)
})
})
多个请求都成功,但是请求之间没有关系
const p = Promise.all([p1, p2, p3]).then(function () {
Three = One + Two
})
多个请求只需要一个成功就做逻辑处理
const p = Promise.race([p1, p2, p3]);
axios多个异步请求全部成功之后处理的业务请求封装
/**
* 传入多个promise的值,当请求成功之后统一反馈,做逻辑处理
* */
allPromise: function(promise1,promise2){
// 将数组对象转为了数组
var userPromise = Array.prototype.slice.apply(arguments);
console.dir(userPromise);
// 添加断点调试
debugger
var promiseObj = new Promise(function(resolve, reject){
axios.all(userPromise).then(axios.spread(function () {
resolve(arguments);
}),function(){
reject(arguments);
});
});
return promiseObj;
},
使用案例
// 获取工厂的信息
var getorgInfoPromise = getData.getRestful("getWarehousesByFacotryid", {id: whOrgId});
//拼装查询参数
var queryParam = {
status: nodeObj.status,
whOrgId: whOrgId
}
// 根据工厂ID 获取下面的库房信息列表
var getWarehousesByFacotryidPromise = getData.postRestful("searchWarehouseInfo", {
pageSize: pageSize,
pageNum: current
}, queryParam);
// 当两个请求同时返回之后触发的事件
getData.allPromise(getorgInfoPromise, getWarehousesByFacotryidPromise).then(function (responseObj) {
var getorgInfoPromiseRes = responseObj[0];
var getWarehousesByFacotryidPromiseRes = responseObj[1];
// 状态码为0 表示请求成功
if (getorgInfoPromiseRes.data.resultCode == 0 && getWarehousesByFacotryidPromiseRes.data.resultCode == 0) {
var treeInfo = {
// 点击仓库类型
type: "org",
// 列表信息
listInfo: getWarehousesByFacotryidPromiseRes.data,
// 详细信息
detailInfo: getorgInfoPromiseRes.data
}
that.totalNum = getWarehousesByFacotryidPromiseRes.data.totalNum;
that.treeClickAction(treeInfo);
}
});