ES6_Promise(七)

回调函数

1
2
3
4
5
6
7
8
9
10
function myAsync(callback){
setTimeout(function(){
console.log('执行完成');
callback('data');
}, 2000);
}

myAsync(function(data){
console.log(data);
});

Promise 解决了什么痛点

回调地狱 代码如下

1
2
3
4
5
6
7
8
9
10
11
myAsync(function(data){
//第一个请求成功接收到数据 然后根据数据触发第二次请求
console.log('第一个请求完成!')
myAsync2(function(data){
console.log('第二个请求完成!')
myAsync3(function(data){
console.log('第三个请求完成!')
//一直一直的回调 排错是很困难的 代码也恶心
})
})
})

我的第一个Promise使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
let myPromise = new Promise(function(resolve, reject){
//当异步代码执行成功时,我们才会调用resolve(...),
// 当异步代码失败时就会调用reject(...)
//使用setTimeout(...)来模拟异步代码 实际可以是Ajax请求
console.log('异步请求中');
setTimeout(function(){
resolve("成功!"); //2秒后代码执行成功 调用resolve
}, 2000);
});

myPromise.then(function(successMessage){
//successMessage的值是上面调用resolve(...)方法传入的值.
console.log("success! " + successMessage);
});

解决回调地狱之链式操作

Promise的优势在于:

  • 可以在then方法中继续写Promise对象并返回,然后继续调用then来进行回调操作。 是不是有种jquery的感觉!

链式操作的用法

  • Promise只是能够简化层层回调的写法,比传递callback的方式简单
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
function myAsync1(){
var p = new Promise(function(resolve, reject){
//做一些异步操作
setTimeout(function(){
console.log('异步1完成');
resolve('data1');
}, 1000);
});
return p;
}
function myAsync2(){
var p = new Promise(function(resolve, reject){
//做一些异步操作
setTimeout(function(){
console.log('异步2完成');
resolve('data2');
}, 2000);
});
return p;
}
function myAsync3(){
var p = new Promise(function(resolve, reject){
//做一些异步操作
setTimeout(function(){
console.log('异步3完成');
resolve('data3');
}, 2000);
});
return p;
}
//依次的异步操作
myAsync1()
.then(function(data){
console.log(data);
return myAsync2();
})
.then(function(data){
console.log(data);
return myAsync3();
})
.then(function(data){
console.log(data);
});

reject( )是什么鬼?

就是异步操作通常有两种结果一个是成功一个是失败

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
function myAsync(){
var p = new Promise(function(resolve, reject){
//做一些异步操作
setTimeout(function(){
console.log('异步1完成');
var num = Math.random()*100;
if(num>60){
resolve('运气不错通过啦!'+num);
}else{
reject('太差了,分不够!'+num)
}

}, 1000);
});
return p;
}
myAsync()
.then(
function(data){
console.log('resolved');
console.log(data);//成功了 你手气不错!
},
function(reason, data){
console.log('rejected');
console.log(reason);//哎呦 挺倒霉啊! 再来一次吧!!
}
);

catch( ) 你肯定听过 try …catch…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function myAsync(){
var p = new Promise(function(resolve, reject){
//做一些异步操作
setTimeout(function(){
console.log('异步任务完成');
resolve('data');
}, 1000);
});
return p;
}
myAsync()
.then(function(data){
console.log('resolved');
console.log(data);
console.log(xxxx.xxxx); //此处的xxxx.xxxx未定义 报错
})
.catch(function(err){
console.log('rejected');
console.log(err);
});

all( )

Promise的all方法提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行回调。

1
2
3
4
5
Promise
.all([myAsync1(), myAsync2(), myAsync3()])
.then(function(results){
console.log(results);
});
  • 用Promise.all来执行,all接收一个数组参数,里面的值最终都算返回Promise对象。
  • 这样,三个异步操作是并行执行的,等到它们都执行完后才会进到then里面。
  • 那么,三个异步操作返回的数据哪里去了呢?
  • 都在then里面呢,all会把所有异步操作的结果放进一个数组中传给then,就是上面的results。

race( )

all( ) 的效果实际上是 ==>以”执行时间最慢的”为准执行回调

race( ) 以最快的为准
race的用法与all一样,把上面myAsync3的延时改为0.5秒运行

1
2
3
4
5
6
Promise
.race([myAsync1(), myAsync2(), myAsync3()])
.then(function(results){
//返回三个异步请求最快的那个
console.log(results);
});