萌新如何理解Promise对象

一.Promise是啥

1.阮大佬的解释

2.看不懂,直接打印

能够看到,这是个构造函数,本身有all,race,reject,resolve方法,原型上有 then,catch方法javascript

3.特色

  • 只有三种状态pending(正在进行),fulfilled(已成功),rejected(已失败)
  • 只有两种状态转换
    • pending===>fulfilled
    • pending===>rejected
  • 状态一旦转换,不会再改变,且promise对象没法自动销毁,任什么时候候均可以获取执行结果

二.啥也无论,用了再说

1.new一个先

let p = new Promise((resolve,reject)=>{
    console.log('123')
    setTimeout(()=>{
        console.log('执行结束')
        resolve(321)
    },2000)
})
复制代码

结果:
java

上面先执行了随便什么操做,两秒后执行了resolve,打印了执行结束es6

啥是resolve和reject?

已经知道这是在构造函数Promise上的方法,es6标准上讲resolve是将异步操做状态从pending转为fulfilled,而reject是将状态从pending转为rejectedajax

看不懂?那继续show you the code数组

2.then方法,以及为何promise支持链式操做?

show you the code

p.then((data)=>{
    console.log(data)
})
复制代码

看结果返回了一个promise对象,咱们知道promise原型上有then方法,所以能够链式操做,很爽!!!promise

打印了321,说明resolve传出的数据咱们能够在then中操做,所以即可以在then中为异步操做的成功或失败状态后设置回调函数,让代码看起来更像同步操做.(解决了回调地狱这个事儿)异步

关于什么是回调地狱,参考:async

[juejin.im/post/5ae7aa…]:函数

简单理解就是函数做为参数层层被调用,会是代码耦合度极高,不利于维护post

提问:还有什么别的方法能够解决嘛?

tip:es7中的async/await =====>这被称为解决异步问题的终极方法

3.造一个函数做为参数层层调用的例子

小明跟爸爸说小明要吃烤肉,爸爸说让小明去买材料,买完材料回来爸爸制做,制做完小明就赶忙吃了溜(就不刷碗!!!!)

先定义几个方法

let async1 = () => {
    let p = new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('买材料')
            resolve('买完材料了')
        }, 2000)
    })
    return p
}
let async2 = () => {
    let p = new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('制做')
            resolve('制做完成,赶忙吃')
        }, 2000)
    })
    return p
}
let async3 = () => {
    let p = new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('吃完赶忙溜')
            resolve('就不刷碗')
        }, 2000)
    })
    return p
}
复制代码

如何描述上面的例子?

show you the code

async1().then((data) => {
    console.log(data)
    return async2()
}).then((data) => {
    console.log(data)
    return async3()
}).then((data) => {
    console.log(data)
})
复制代码

运行结果

一步一步,上一步函数的调用结果做为下一步的参数,将异步操做以同步操做的流程表达出来,避免层层嵌套,完美.

4.reject是啥?

通过上面的例子,应该大概了解了promise是啥,可是里面好像还有个reject咱们还没看,来,继续上面的例子

众所周知,小明是一个调皮的可是注意力不集中的好孩子,在路上,他发现了好甜的水果糖,因而买了水果糖,结果回到家到了第二调用,便带了个error

show you the code

// 改一下async1()
let async1 = () => {
    let p = new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('买材料')
            console.log('看到糖果')
            console.log('买了糖果')
            if(/*买对了*/ 0){
                resolve('买了材料')
            }else{
                reject('买了糖果')
            }
        }, 2000)
    })
    return p
}


// 描述故事
async1().then((data) => {
    console.log(data)
    return async2()
},(err)=>{
    console.log('买错了,快滚')
    return
})
//为了描述上面的例子,这里只作了第一步调用
复制代码

结果:

由结果看,then(parm1,parm2)的两个参数,第一个为处理resolve的情况,给resolve添加函数处理,而第二个参数为处理reject的情况,两个参数都为处理函数.

第一个处理函数的参数为resolve传过来的数据,第二个的参数为reject传过来的数据.

5.catch?

单词的一次就是捕获,因此做用是捕获异常,参数为异常处理函数,也就是跟then的第二个参数同样,所以再也不赘述,可是catch有本身的独特的做用(否则凭啥存在)

话很少说,show you the code

const fun = () => {
    let p = new Promise((resolve, reject) => {
        resolve(123)
    })
    return p
}

fun().then((data)=>{
    console.log(data)
    console.log(names)
})
复制代码

上面的例子运行会报names is not defined 的错误,并且不会继续运行了,若是后面有代码会直接中断,而若是加了catch

fun().then((data)=>{
    console.log(data)
    console.log(names)
}).catch((res)=>{
    console.log('出错咯')
}).then((data)=>{
    console.log('123')
})
复制代码

看结果

由此,代码出错,会被catch捕获,并作处理,而后能够继续运行代码.

6.race和all方法

all方法

仍是用小明的例子

咱们先把延时时间改一下,好比async1改成4s,async2改成3s,async3改成2s

Promise.all([async1(),async2(),async3()])

// all里传的参数为promise实例的数组
复制代码

看结果

all方法提供的是并行执行异步操做的能力

Promise.all()方法的参数为一个数组,数组里各元素均为promise实例,若是不是,会先转换为promise实例.

注意

  • 所有执行完异步操做才会进入then处理每一个异步操做的返回数据.

简单理解就是以跑的慢的为准,跑的慢的跑完了才一块儿处理返回结果.

使用场景

  • 加载静态资源所有完成后才须要渲染处理的时候

race方法

相对all方法,这个就是跑的快的为准,有跑完了的就直接执行then里处理函数

因而上面的代码改用race方法后

Promise.race([async1(),async2(),async3()]).then((datas)=>console.log(datas))
复制代码

结果

async3执行的最快,跑完后便直接处理打印了resolve返回的数据==>'就不刷碗'

使用场景

  • 给ajax等异步操做请求设置超时时间

至此,最经常使用的promise的方法都已经介绍完毕.

相关文章
相关标签/搜索