Promise的基本用法


Promise是什么?

Promise是一种异步解决方案,它是一个构造函数,可以接收一个参数为函数,函数内有两个参数为resolve,reject这两个参数是异步操作成功后或失败后调用的回调函数。

Promise的特点

(1) Promise简单的来说它就是一个容器, Promise对象的状态不受外界的影响, 它就三种状态:pending(进行中)、fulfilled(已成功)、reject(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作结果都无法改变这个状态。

(2) 一旦状态发生改变,就不会再变,任何时候都可以得到这个结果,Promise状态改变只有两种可能,从pending到fulfilled或者从pending到reject,只要状态确定之后,就不会再变了,会一直保持这个结果。

(3) 一旦创建Promise就会立即执行,中途无法取消。

为什么要用Promise?

Promise解决了嵌套回调函数的 " 回调地狱 " Promise是链式的它比回调函数看着没那么恶心,不像回调函数嵌套那么多层。

Promise的优势在于,可以在then方法中继续写Promise对象并返回,然后继续调用then来进行回调操作。


下面写一个基本的Promise用法

var p = new Promise(function(resolve,reject){
    resolve('执行了')
})

p.then(function(data){
    console.log(data)  // 执行了
})

上面代码中,resolve函数是表示成功, then第一个参数的回调函数,接收上面resolve函数中的参数数据。

下面再看一个失败的状态

var p = new Promise(function(resolve,reject){
    reject('错误了')
})
 p.then(function(data){
    console.log(data)
},function(error){
    console.log(error)  // 错误了
})

上面代码中,then方法中的第二个参数是接收失败时的状态函数。

.catch语法,该方法也是捕获错误的。

p.then(function(data){
    console.log(data)
}).catch(function(error){
    console.log(error)  // 错误了
})

看到上面的代码,可能有的小伙伴就会说,catch和then方法的第二个参数同样都是捕获的错误的,那么它俩有什么区别呢?

then第二个参数

var p = new Promise(function(resolve,reject){
    resolve('执行')
})

p.then(function(data){
    console.log(data);  // 执行
    console.log(num);
},function(error){
    console.log(error)
})
效果:
not defined

上面的代码,说是then的第二个参数是捕获错误的,但是它只捕获Promise实例里的错误,then里面有一个console.log(num) , num没有声明 报错 , 它就捕获不到,catch方法就可以捕获的到,所以我们一般都是使用catch方法。

var p = new Promise(function(resolve,reject){
    resolve('执行')
})
p.then(function(data){
    console.log(data);
    console.log(num);
}).catch(function(error){
    console.log(error) // 可以捕获的到
})
not defined

上面代码,catch方法可以捕获的到错误,catch可以说是比较强大的。

then链式操作用法

var p = new Promise(function(resolve,reject){
    resolve('执行')
})
p.then(function(data){
    console.log(data);  // 执行
    return 123;
}).then(function(data){
    console.log(data)  // 123 
    return 456;
}).then(function(data){
    console.log(data) // 456
})

上面代码的链式操作,这方法非常的棒,return返回值就是下一个then要捕获的数据,这方法就相当于我们回调函数的层层嵌套,然而Promise链式操作更简洁。

Promise.all方法

all方法非常的方便,它可以执行多个异步操作 \color{red}{前提必须都是resolve状态} ,并且在一个回调中处理所有的返回数据

function fn1(){
    return new Promise(function(resolve,reject){
        setTimeout(function(){
            resolve('我是fn1')
        },1000)
    }) 
}

function fn2(){
    return new Promise(function(resolve,reject){
        setTimeout(function(){
            resolve('我是fn2')
        },300)
    }) 
}

function fn3(){
    return new Promise(function(resolve,reject){
        setTimeout(function(){
            resolve('我是fn3')
        },5000)
    }) 
}

Promise.all([fn1(),fn2(),fn3()]).then(function(data){
    console.log(data)
})

上面代码Promise.all方法参数接收一个数组,它的执行呢,数组内的三个参数必须都为resolve状态,都是成功的才行,有一个reject状态就会报错,终止运行,上面代码的定时器异步操作5秒后执行,它会看三个定时器的谁的时间最长而等待它被执行,所以它会在5秒之后,再返回Promise。

Promise.race方法

race方法也是接收一个数组,\color{red}{参数必须是Promise对象},只返回其中的一个值,就是定时器谁的时间最短就返回谁,该方法一般都是在进行访问超时时间。

function fn1(){
    return new Promise(function(resolve,reject){
        setTimeout(function(){
            resolve('我是fn1')
        },1000)
    }) 
}

function fn2(){
    return new Promise(function(resolve,reject){
        setTimeout(function(){
            resolve('我是fn2')
        },300)
    }) 
}

function fn3(){
    return new Promise(function(resolve,reject){
        setTimeout(function(){
            resolve('我是fn3')
        },5000)
    }) 
}

Promise.race([fn1(),fn2(),fn3()]).then(function(data){
    console.log(data)  // fn2 
})

上面代码只执行了一个 fn2


下面写一个返回请求超时的列子。

var p = Promise.race([
    fetch('http://jsonplaceholder.typicode.com/users'),
    new Promise(function (resolve, reject) {
          setTimeout(function(){
               reject(new Error('当前网络不可用~'))
          },3000)
    })
]);

p.then(function(data){
    return data.json()
}).then(function(data){
    console.log(data)
}).catch(function(error){
    console.log(error)
})

Promise.resolve方法

该方法是转换为Promise对象,如果转换的该参数不是Promise对象,该方法就会自己新生成一个新的Promise对象,状态为resolve,如果是Promise对象,就不做任何的操作,状态直接为resolve。

Promise.resolve('aaa');

//相当于

new Promise(function(resolve,reject){
      resolve('aaa')
})

Promise.reject方法

该方法跟Promise.resolve一样,同上,该方法都不怎么使用,了解就行。

Promise.reject('aaa');

//相当于

new Promise(function(resolve,reject){
    reject('aaa')
})

下面看一下Promise和其它的执行顺序。

var p = new Promise(function(resolve,reject){
    resolve('我是then调用的')
    console.log('我是立即执行')
})

p.then(data=>console.log(data))

console.log(1)

setTimeout(()=>{
    console.log('我是定时器')
},0)

效果:


执行顺序

解析:

  • Promise创建后就会立即执行,中途无法取消。
  • then方法和定时器都是异步的,前者会加入到本轮执行队列的尾部,后者则会加入下一个队列中,所以会先让console.log(1)执行。
  • then执行是在本轮的结束时才执行。
  • 定时器执行是在下一轮中所以它最后执行。

希望通过本文章能让你有所收获。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,717评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,501评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,311评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,417评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,500评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,538评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,557评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,310评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,759评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,065评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,233评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,909评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,548评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,172评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,420评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,103评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,098评论 2 352

推荐阅读更多精彩内容

  • 信念是一棵树 它生长在我们每个人的心里 信念是一颗四季常青之树 它的种子在我们的心中生根发芽 信念之花却绽放在我们...
    柠檬遇上姜阅读 396评论 0 3
  • 感恩今天参加孩子学校的毕业典礼,收获了满满的幸福感 感恩上帝赐我一个如此可爱的宝贝 感恩一家人可以这样简单幸福的在...
    混混小花阅读 147评论 0 0
  • 两人一狗一座池城 而我在闹 他在笑 其实,考虑买只狗狗也有些...
    酒浓情伤阅读 223评论 2 1
  • 1 检查了例子controller模块与对应的jsp,发现jsp没有实现,基于当前试验基本完成,对于整个框架有了基...
    hayes0420阅读 116评论 0 0