promise控制异步流程;
promise就是个构造函数,参数为一个函数
构造函数一般使用其实例进行操作,如何得到一个构造函数的实例呢?
1)new Promise(参数:函数);
2)参数为一个函数,这个函数同样也有两个参数 resolve reject,这两个参数也是函数
resolve执行后返回promise的成功状态,
reject执行后返回promise的错误状态。
基本使用形式:
// 将一段同步代码封装成一个promise实例
// 这个实例内部调用resolve,返回成功状态,并将结果通过resolve传递
var p = new Promise(function(resolve,reject){
console.log('ok');
resolve('结果')
})
// 通过调用promise实例上的then方法来获取resolve传递的数据
p.then(function(data){
console.log(data);
})
1. Promise的特点:
- 只要一 new ,promise就执行了,并且得到一个promis实例;
- promis实例内部结果通过resolve进行传递;
- 通过调用promise实例的then方法获取resolve传递的结果。
一般用promise干什么呢?
包装异步执行代码,将其转化为同步执行的样式,
比方发送一个ajax常规方法:
$.get("https://cnodejs.org/api/v1/topics?tab=share",function(data){
console.log(data);
})
转化为Promise如下:
let p = new Promise((resolve,reject)=>{
$.get("https://cnodejs.org/api/v1/topics?tab=share",function(data){
resolve(data)
})
});
p.then((data)=>{
console.log(data);
})
2. 在实际开发中的使用
在开发中一般不会把new Promise直接暴露在外面,而是封装成一个函数,上面代码修改如下:
function fn(){
let p = new Promise((resolve,reject)=>{
$.get("https://cnodejs.org/api/v1/topics?tab=share",function(data){
resolve(data)
})
});
return p
}
fn().then((data)=>{
console.log(data)
})
根据作用需求/场景来学习,需求如下:
比方一个页面加载进来,需要发送5个ajax请求,并需要把结果统一经行处理:
首先大家按照大家已有的知识点来思考一下如何解决呢?
代码如下
$(function(){
var arr = []
$.get("https://cnodejs.org/api/v1/topics?tab=ask",function(data){
arr.push(data);
$.get("https://cnodejs.org/api/v1/topics?tab=job",function(data){
arr.push(data);
$.get("https://cnodejs.org/api/v1/topics?tab=good",function(data){
arr.push(data);
$.get("https://cnodejs.org/api/v1/topics?tab=share",function(data){
arr.push(data);
console.log(arr)
})
})
})
})
})
简称 回调地狱 缺点耗费时间,看图说话:
创新一下,代码如下:
(function () {
var count = 0;
var arr = [];
function handle() {
if (count === 4) {
console.log(arr);
}
}
$.get("https://cnodejs.org/api/v1/topics?tab=good",function(data){
arr.push(data);
count++;
handle()
})
$.get("https://cnodejs.org/api/v1/topics?tab=job",function(data){
arr.push(data);
count++;
handle()
})
$.get("https://cnodejs.org/api/v1/topics?tab=share",function(data){
arr.push(data);
count++;
handle()
});
$.get("https://cnodejs.org/api/v1/topics?tab=ask",function(data){
arr.push(data);
count++;
handle()
});
})();
但是这种依然有个缺点,得写监控函数,每次回调都会调用监控函数,耗费性能,还有其他方法吗?
查看network 中的waterfall
:
用Promise怎么实现呢?
代码如下:
$(function(){
// 封装一个promise;将url提取出来;
var p = function(url){
return new Promise(function(resolve,reject){
$.get(url,function(data){
resolve(data);
})
})
}
Promise.all([
p("https://cnodejs.org/api/v1/topics?tab=good"),
p("https://cnodejs.org/api/v1/topics?tab=share"),
p("https://cnodejs.org/api/v1/topics?tab=ask"),
p("https://cnodejs.org/api/v1/topics?tab=job"),
]).then(function(result){
console.log(result);
})
})
waterfall图如下: