Node.js开发——一文教会你Promise实操

是什么

是一个构造函数,用来封装一个异步操作,并可以获得其结果

使用场景-异步编程:

fs文件操作

数据库操作(mongoDb)

Ajax

定时器

promise之前使用回调函数处理异步编程

为什么要用promise

  1. 指定回调函数的方式更加灵活
    1. 旧的:必须在启动异步任务前指定回调函数
    2. promise:启动异步任务 -> 返回promise对象 -> 给promise对象绑定回调函数(甚至可以在异步任务结束之后指定一个或多个)
  2. 支持链式调用,解决回调地狱的问题

promise的使用

1、构造

promise是一个构造函数,参数是一个函数,也就是将被异步执行的函数,该函数中有两个参数:

  • resolve:函数执行成功之后调用,仅将promise对象的状态设置为「成功」
  • reject:函数执行失败之后调用,仅将promise对象的状态设置为「失败」
const p = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        // let n = rand(1,100);
        let n = 10;
        if(n <= 30){
            resolve(n);//将promise对象的状态设置为「成功」,可以带出参数,供后面的then 回调函数 中使用
        }else{
            reject(n);//将promise对象的状态设置为「失败」,可以带出参数,供后面的then 回调函数 中使用
        }
    },1000);
});

2、调用then方法

指定回调函数,then方法有两个参数:

  • param1:promise对象是成功时的回调函数,即异步方法成功后的回调
  • param2:promise对象是失败时的回调函数,即异步方法失败后的回调
p.then((value)=>{
    console.log('恭喜,中奖号码为:'+value);
},(reason)=>{
    console.log('加油,您的号码为:'+reason);
})

常见问题

  1. 当用then为一个promise对象指定多个回调时,当promise的状态改变时,所有的回调都会执行
  2. promise改变状态和指定回调方法的先后问题?
    1. 当promise对象的执行器(即参数,函数)是一个同步任务时(直接调用resolve()/reject()),先改变promise状态,再指定回调
    2. 当promise对象的执行器(即参数,函数)是一个异步任务时(比如设置定时器),先指定回调,再改变promise状态

promise对象

状态 promiseState

状态值

是promise实例对象中内置的一个属性:promiseState

  • pending 未决定的,初始化的默认值
  • resolved / fullfilled 成功
  • rejected 失败

状态的改变

  1. 从pending变为resolved
  2. 从pending变为rejected

说明:

  • 状态的改变只有这两种,且一个promise对象的状态值只能被改变一次
  • 无论成功还是失败,都会有一个结果数据
  • 成功的结果数据一般称为value,失败的结果数据一般称为reason

结果属性 PromiseResult

存储promise对象成功或失败的结果,也就是异步任务成功或失败的结果

只有resolve()、reject() 两个函数可以对promiseResult进行修改

promise执行流程

API

Promise.resolve()

Promise函数对象级别的方法

使用:Promise.resolve(value=>{})

value:成功的数据或Promise对象

  1. 如果传入的参数不是Promise对象,则返回结果为一个成功的Promise对象
  2. 如果传入的参数是Promise对象,则参数的结果决定了resolve()的结果

结果:返回一个成功或失败的Promise对象

Promise.reject()

Promise函数对象级别的方法

使用:Promise.reject(reason=>{})

结果:返回一个失败的Promise对象,无论参数是什么

Promise.all()

参数:promises:包含n个promise的数组

结果:返回一个新的promise对象,只有所有的promise都成功才返回成功,只要有一个失败就直接失败;结果值是promise数组的结果组成的数组

Promise.race()

参数:promises:包含n个promise的数组

结果:返回一个新的promise,第一个完成的promise对象的结果就是最终的结果状态

promise的链式调用

利用then() 返回的是一个promise对象进行实现

1、使用

let p2 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        resolve('ok');
    },1000)
});

//链式调用
p2.then(value=>{
    return new Promise((resolve,reject)=>{
        resolve('success');
    })
}).then(value=>{
    console.log(value)
}).then(value=>{
    console.log(value)
})

2、异常穿透

在then链式调用的最后指定失败的回调,前面出现了任何问题,都会传到最后失败的回调中处理

let p2 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        resolve('ok');
    },1000)
});
p2.then(value=>{
    return new Promise((resolve,reject)=>{
        resolve('success');
    })
}).then(value=>{
    console.log(value);
}).then(value=>{
    console.log(value);
}).catch(reason=>{
    console.warn(reason);
})

3、中断promise链

当使用promise的then链式调用时,在中间中断,不再调用后面的回调函数

方法:返回一个pending状态的promise对象

return new Promise(()=>{})

async函数和await表达式

结合使用无需再写回调函数!

写法形式类似于同步,但内部是异步执行的

async

  • 用于修饰一个函数
  • 函数的返回值是一个promise对象
  • promise对象的结果由async函数执行的返回值决定
    • 如果返回值是一个非promise类型的数据,结果就是一个成功的promise对象,结果值就是return的值
    • 如果返回值是一个promise类型的数据,return的结果就决定了函数的返回结果
    • 抛出异常,返回结果是失败的promise对象

await表达式

  1. await右侧的表达式一般是一个promise对象,但也可以是其他值
  2. 若表达式的右侧是promise对象,await返回的是promise成功的值
  3. 若表达式是其他值,直接将此值作为await的返回值
  4. await必须写在async函数中,但async函数中可以没有await
  5. 如果await的promise失败了,就会跑出异常,需要通过try...catch捕获处理
  6. await会阻塞进程,会暂停当前async function()的执行,等待promise执行完成
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值