浅谈promise

这里只谈下平时容易忽视的点。

扁平化处理

promise作为强大的异步解决方法,在最开始使用时往往会陷入到一个误区里面,例如我请求了一个省份id,然后需要省份id去请求市级id,接着还需要市级id获取区县级id。
很多人可能就直接这么写了

//假设使用ajax请求,默认返回的promise对象
function getData() {
	api.getProvince().then(provinceId => {
		api.getPCCountScriptSummary(provinceId).then(cityId => {
			api.getCounty(cityId).then(res => {
				// 获取到区县数据
			})
		})
	})
}

刚开始学习promise的时候我也写过这种代码,虽然看似使用了promise,但是依旧是层层嵌套的回调地狱,没有将promise的扁平化特性发挥出来。

代码改造

function getData() {
	api.getProvince().then(provinceId => {
		return api.getPCCountScriptSummary(provinceId)
	}).then(cityId => {
		return api.getCounty(cityId)
	}).then(res => {
		// 获取到区县数据
	})
}

这样就达到了promise扁平化代码的特点。

错误捕获

promise里面的错误捕获有两种方式,一种直接放给then方法里面添加第二个参数,一种直接在最后进行catch捕获。

let  promiseDemo = new Promise(function(resolve, reject) {
	setTimeout(() => {
		reject(0)
	}, 1000)
})
promiseDemo.then(res => {
	console.log(res);
}, err => {
	console.log(err, 'reject第二个参数捕获的异常');
}).then(() => {
	console.log(1);
}).then(() => {
	console.log(2);
})

这样的方式会发先打印出
0 ‘reject第二个参数捕获的异常’
1
2
由此我们可以知道这样的异常捕获不会阻断链式调用。

let  promiseDemo = new Promise(function(resolve, reject) {
	setTimeout(() => {
		reject(0)
	}, 1000)
})
promiseDemo.then(res => {
	console.log(res);
}).then(() => {
	console.log(1);
}).then(() => {
	console.log(2);
}).catch(err => {
	console.log(err);
})

打印出0,由此可见catch方式捕获异常会直接阻断链式调用。
简单总结下就是reject后的东西,一定会进入then中的第二个回调,如果then中没有写第二个回调,则进入catch,进入catch则代码运行结束。

甚至我们可以进行组合使用

let  promiseDemo = new Promise(function(resolve, reject) {
	setTimeout(() => {
		reject(0)
	}, 1000)
})
promiseDemo.then(res => {
	console.log(res);
}, err => {
	console.log(err, 'reject');
}).then(() => {
	reject(1)
}).then(() => {
	console.log(2);
}).catch(err => {
	console.log(err, 'catch');
})

打印出
0 ‘reject’
1
2

静态方法

简单介绍下promise的几个静态方法

Promise.all

let  promiseDemo = new Promise(function(resolve, reject) {
	setTimeout(() => {
		resolve(0)
	}, 1000)
})
let  promiseDemo1 = new Promise(function(resolve, reject) {
	setTimeout(() => {
		resolve(1)
	}, 1000)
})
let  promiseDemo2 = new Promise(function(resolve, reject) {
	setTimeout(() => {
		resolve(2)
	}, 1000)
})
Promise.all([promiseDemo, promiseDemo1, promiseDemo2]).then(res => {
	console.log(res);
})

简单说就是当所有promise 成功返回就会返回一个结果数组,数组顺序与promise 时的数据一致。若有一个promise 失败则进入catch,并终止剩余promise 。(可以简单理解为promise 的&&操作)

Promise.allSettled
只需将方法替换为allSettled即可

Promise.allSettled([promiseDemo, promiseDemo1, promiseDemo2]).then(res => {
	console.log(res);
})

改方法是等待所有promise 结束后,无论成功失败,都会生成一个对象数组,每个对象对应每个promise ,对象里面有两个参数,一个参数是status,表示promise的状态,一个参数是vlaue,表示响应的值。

[
  {
	status: "fulfilled",
	vlaue: "1"
  }
]

Promise.any
该方法与Promise.all对应,当其中的一个 promise 成功,就返回那个成功的promise的值。

Promise.race
当其中任何一个promise对象返回结果(无论成功或者失败),则结束执行。

Promise.reject
返回一个状态为失败的Promise对象,并将给定的失败信息传递给对应的处理方法。

Promise.reject(new Error('fail')).then(function() {
  // not called
}, function(error) {
  console.error(error); // Stacktrace
});

Promise.resolve
返回一个正确的promise结果,还可以利用此方法将非promise格式的数据转换为promise对象。如果该值是thenable(即,带有then方法的对象),返回的Promise对象的最终状态由then方法执行决定。

//转换为promise格式
promise.resolve('ok')  // Promise {<fulfilled>: 'ok'}
//带then方法的对象
let obj = {
	then: function(onFulfilled, onRejected) {
		onFulfilled('ok')
	}
}

Promise.resolve(obj).then(res => {
	console.log(res); // ok
})
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值