Promise
是JavaScript ES6中的一个新特性,用于异步处理。在没有Promise
之前,做异步调用通常使用callback函数的方式:
function callback(data){
console.log(data);
}
function foo(data,callback){
//模拟延时返回
setTimeout(callback,2000,data);
}
foo('hello!',callback);
执行代码 一段时间后 控制台打印hello!
通常我们对异步调用的使用会更加复杂,比如异步调用有可能执行成功或者失败,可能存在着嵌套,多个异步调用全部完成后再执行某些代码等等。用上面的方式,这些需求也是可以满足的,但是为了利于代码的易读、复用、标准化等等需求,ES6提供了Promise来完成这些任务。
一个最简单的Promise
例子:生成一个随机数,如果大于0.5则成功,否则失败:
// 当随机数大于0.5则成功,否则失败
function foo(resolve, reject){
var time = Math.random();
setTimeout(function(){
if(time<0.5){
reject(time);
}else{
resolve(time);
}
},time*1000);
}
new Promise(foo)
.then(result=>console.log('成功'+result))
.catch(result=>console.log('失败'+result))
可见Promise
把执行过程,处理结果,错误处理都分开了。
当有嵌套执行异步操作,我们需要任何任务失败则不再继续,并执行错误处理函数,Promise
也可以让整个流程变得简洁。下面是一个Promise
嵌套执行异步操作的例子:
// 定义被除数对象
function Dividend(value){
var that = this;
this.value = value;
this.divided = function(divisor){
console.log('计算 '+that.value+'除以'+divisor+'...')
return divide(that.value,divisor);
}
}
function divide(num,num1){
return new Promise(function(resolve,reject){
if(typeof(num) === 'number' && typeof(num1) === 'number'&& num1!==0){
//通过resolve返回一个Dividend对象
setTimeout(resolve, 500,new Dividend(num/num1));
}else{
setTimeout(reject, 500, '参数不是数字或者除数为0');
}
});
}
运行:
// 正确的运算
divide(100,2)
.then(dividend=>dividend.divided(2))
.then(dividend=>dividend.divided(2))
.then(dividend=>dividend.divided(3))
.then(dividend=>console.log("结果:"+dividend.value))
.catch(reason=>console.log("错误:"+reason));
// 错误的运算
divide(100,2)
.then(dividend=>dividend.divided(2))
.then(dividend=>dividend.divided(0))
.then(dividend=>dividend.divided(3))
.then(dividend=>console.log("结果:"+dividend.value))
.catch(reason=>console.log("错误:"+reason));
结果:
// 正确的运算
计算 50除以2...
计算 25除以2...
计算 12.5除以3...
结果:4.166666666666667
// 错误的运算
计算 50除以2...
计算 25除以0...
错误:参数不是数字或者除数为0
除了串联执行若干异步任务外,Promise
还可以并联执行异步任务。
并联执行的逻辑分为两种
- 当所有Promise执行完毕后执行任务
- 当任意一个Promise执行完毕后执行任务
// 当所有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) {
// 获得一个Array: ['P1', 'P2'],结果的顺序和all函数中Promise的顺序一致
console.log(results); });
//当任意一个Promise执行完毕后执行任务
var p1 = new Promise(function (resolve, reject) {
setTimeout(resolve, 500, 'P1');
});
var p2 = new Promise(function (resolve, reject) {
setTimeout(resolve, 600, 'P2');
});
// 由于p1执行较快,Promise的then()将获得结果'P1'。p2仍在继续执行,但执行结果将被丢弃。
Promise.race([p1, p2]).then(function (result) {
console.log(result); // 'P1'
});
网友评论