javascript的单线程处理总是让人头疼不已,异步执行的方法总要使用回调方法来处理它的反馈结果。一层套一层的传参往往会使你的代码变得一团糟……如何优雅的处理异步执行方法的代码?
Promise是一个不错的解决方式!
什么是Promise?
它是javascript标准库解决处理异步方法状态,返回值的构造函数。
定义方式:var pro = new Promise(function(resolve,reject){ ##方法体}),当然你也可以将方法定义到构造函数外面。
参数: resolve 和 reject 为成功和失败调用的方法,你可以在方法中成功后调用resolve失败后调用reject而不用关心这两个方法是如何处理的。
方法:
Promise.prototype.then() AND Promise.prototype.catch()
.then()方法使Promise原型链上的方法,它包含两个参数方法,分别是已成功resolved的回调和已失败rejected的回调
promise.then(
console.log('this is success callback')
)
.catch()的作用是捕获Promise的错误,与then()的rejected回调作用几乎一致。但是由于Promise的抛错具有冒泡性质,能够不断传递,这样就能够在下一个catch()中统一处理这些错误。同时catch()也能够捕获then()中抛出的错误,所以建议不要使用then()的rejected回调,而是统一使用catch()来处理错误
promise.then(
() => { console.log('this is success callback') }
).catch(
(err) => { console.log(err) }
)
同样,catch()中也可以抛出错误,由于抛出的错误会在下一个catch中被捕获处理,因此可以再添加catch()
Promise.all(iterable)
这个方法返回一个新的promise对象,该promise对象在iterable参数对象里所有promise对象都成功的时候才会触发成功,一旦有任何一个iterable里面的promise对象失败则立即触发该promise对象的失败。这个新的promise对象在触发成功状态以后,会把一个包含iterable里所有promise返回值的数组作为成功回调的返回值,顺序跟iterable的顺序保持一致;如果这个新的promise对象触发了失败状态,它会把iterable里第一个触发失败的promise对象的错误信息作为它的失败错误信息。Promise.all方法常被用于处理多个promise对象的状态集合。
var p1 = new Promise(function (resolve, reject) {
setTimeout(resolve, 500, 'P1');
});
var p2 = new Promise(function (resolve, reject) {
setTimeout(resolve, 600, 'P2');
});
// 同时执行p1和p2,并在它们都完成后执行then:
Promise.all([p1, p2]).then(function (results) {
console.log(results); // 获得一个Array: ['P1', 'P2']
});
Promise.race(iterable)
当iterable参数里的任意一个子promise被成功或失败后,父promise马上也会用子promise的成功返回值或失败详情作为参数调用父promise绑定的相应句柄,并返回该promise对象。
p1.then(function (result) {
console.log('成功:' + result);
});
Promise.reject(reason)
返回一个状态为失败的Promise对象,并将给定的失败信息传递给对应的处理方法Promise.resolve(reason)
function test(resolve, reject) {
var timeOut = Math.random() * 2;
log('set timeout to: ' + timeOut + ' seconds.');
setTimeout(function () {
if (timeOut < 1) {
log('call resolve()...');
resolve('200 OK');
}
else {
log('call reject()...');
reject('timeout in ' + timeOut + ' seconds.');
}
}, timeOut * 1000);
}