Promise多个请求、finally、链式调用学习

文章参考

  1. 阮一峰 ES6 promise
  2. vue实力封装axios

基本语法

早期浏览器兼容: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方法

参考 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);
	}
  });
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值