Promise详解

Promise笔记

异步编程

  • fs 文件操作
    require('fs').readFile('./路径',(err,data)=>{})
    
  • 数据库操作
  • AJAX
    $.get('/server',(data)=>{})
    
  • 定时器
    setTimeout(()=>{},2000)
    

Promise

是ES6引入的js中进行异步编程的新解决方案
旧方案是单纯使用回调函数

  • 语法看来,是一个构造函数,可以进行对象的实例化
  • 功能看来,promise对象可以用来封装一个异步操作并且可以获取其成功/失败的结果值

Promise的状态

指的是实例对象中的一个属性 PromiseState

  • pending 未决定的状态值
  • resoolved / fullfilled 成功的状态值
  • rejected 失败的状态值

状态改变(不能从成功变成失败,也不能从失败变成成功,只能从pending转变)

  • pending变为resolved
  • pending变为rejected
    一个promise对象只能改变一次状态,无论变成成功还是失败,都会有一个结果数据,
    成功的结果数据为value,失败的结果数据为reason

Promise状态的值

指的是实例对象中的另一个属性 PromiseResult
保存的是异步任务 成功或失败 的结果
可以改变PromiseResult的值只有两种:

  • resolve
  • reject

PromiseAPI

  • promise构造函数:Promise(excutor){}
    1.excutor函数:执行器 (resolve,reject)=>{}
    2.resolve函数:内部定义成功时,调用的函数 value=>{}
    3.rehect函数:内部定义失败时,调用的函数:reason=>{}
    excutor会在Promise内部立即同步调用,异步操作再执行器中执行

  • Promise.prototype.then方法:(onResolved,onRejected)=>{}
    1.onResolved函数:成功的回调函数 (value) =>{}
    2.onRejected函数:失败的回调函数 (reason) =>{}
    指定用于得到成功value的成功回调和用于得到失败reason的失败回调返回一个新的promise对象

  • Promise。prototyph.catch方法:(onRejected)=>{}
    1.onRejeted函数:失败的回调函数(reason)=>{}

  • Promise.resolve方法:(value)=>{}
    1.value:成功的数据或promise对象
    返回一个成功/失败的promise对象
    如果传入的参数为 非 Promise类型的对象,则返回的结果为成功的promise对象

    let p1 = Promise.resolve(521)
    

    如果传入的参数为 Promise对象,则参数的结果决定了resolve的结果

    let p2 = Promise.resolve(new Promise((resolve,reject)=>{
        // 参数的结果为成功,p2的结果就是成功的promise对象
        resolve('ok')
        // 参数的结果为失败,p2的结果就是失败的promise对象
        // reject('error')
    }))
    console.log(p2);
    // p2是失败的promise对象,解决报错
    p2.catch(reason=>{
        console.log(reason);
    })
    
  • Promise.reject方法:(reason)=>{}
    1.reason:失败的原因
    总是返回一个失败的promise对象
    无论传入的参数是什么类型 都是失败的promise对象
    即使传入的是成功的Proimise对象,返回的结果依旧为失败的promise对象
    传入什么s失败的结果就是什么

  • Promise.all方法:(promises)=>{}
    1.promises:包含n个promise的数据
    返回一个新的promise,只要所有的promise都成功返回的才是成功的promise,只要有一个失败就直接失败
    成功的结果:每一个promise对象他们的结果组成的一个数组
    失败的结果:在这个数组当中,失败的promise对象是他失败的结果(先出错的primise对象的结果)

  • Promise.race 方法:(promises)=>{}
    1.promises:包含n个promise的数组
    返回一个新的promise,第一个完成的promise的结果状态就是最终的结果状态(不管有多少个promise,只取第一完成的promise对象的结果)


promise的几个关键问题

  • 如何改变 promise的状态
    1.resolve(value)函数:如果当前是pending就会变成resolved/fullfilled(成功)

    resolve('ok') //pending => fullfilled/resolved
    

    2.reject(reason)函数:如果当前是pending就会变成rejected(失败)

    reject('error) //pending => rejected
    

    3.抛出异常:如果当前是pending就会变成rejected(失败)

    throw ''出错了 //pending => rejected
    
  • 一个promise指定多个成功/失败的回调函数,都会被调用吗?
    当promise的状态 pending 改变为对应状态时都会被调用

  • 改变promise状态(resolve/reject)和指定回调函数(then)谁先谁后?
    1.都有可能,默认先执行改变状态在执行指定回调,指定回调then先执行再执行改变状态,(在改变状态中吧同步改成异步)
    2.在执行器中直接调用resolve()/reject(),(同步)就是先改状态再指定回调,也可以.then回调函数中加定时器来延长.then的调用
    3.什么时候才能拿到数据?(回调函数.then什么时候执行 就什么时候拿到数据)
    如果先指定的回调,状态改变以后,再去调用成功或失败的结果
    如果先改变的状态,.then方法在调用的时候就会执行回调函数拿到数据,处理成功或失败的结果

  • promise如何串联多个操作任务
    1.promise的then()返回一个新的promise,可以开成then()的链式调用
    2.通过then的链式调用串联多个同步/异步任务

    let p = new Promise((resolve,reject)=>{
        setTimeout(() => {
            resolve('ok')
        }, 2000);
    })
    
    p.then(value=>{
        // ok
        console.log(value);
        // 返回一个成功的promise
        return new Promise((resolve,reject)=>{
            resolve('success')
        })
    }).then(value=>{
        // success
        console.log(value);
    }).then(value=>{
        // 因为上面的then返回的是一个全新的promise对象,但是他没有返回值,所以这里输出的undifund
        console.log(value);
    })
    
  • promise异常穿透?
    1.当时用promise的then链式调用时,可以再最后指定失败的回调.catch(reason=>{})
    2.前面任何操作出了异常,都会传到最后失败的回调中处理

    let p = new Promise((resolve,reject)=>{
        setTimeout(() => {
            resolve('ok')
            // reject('Error')
        }, 2000);
    })
    
    p.then(value=>{
    
        // console.log('111');
        throw 'error'
    }).then(value=>{
        console.log('222');
    }).then(value=>{
        console.log('333');
    }).catch(reason=>{
        console.log(reason);
    })
    
  • 中断promise链
    有且只有一个方式:返回状态为pending的promise对象

    let p = new Promise((resolve,reject)=>{
        setTimeout(() => {
            resolve('ok')
        }, 2000);
    })
    
    p.then(value=>{
    
        console.log('111');
        // 有且只有一个方式  返回pending状态的promise对象  下面的.then就不会执行了
        return new Promise(()=>{})
    }).then(value=>{
        console.log('222');
    }).then(value=>{
        console.log('333');
    }).catch(reason=>{
        console.log(reason);
    })
    

async 与 await

  • async函数

函数的返回值为promise对象
promise对象的结果由async函数执行的返回值决定

  • await函数

await右侧的表达式一般为promise对象,但也可以是其他值
如果表达式是promise对象。await返回的是promise成功的值
如果表达式是其他值,直接讲此值作为await的返回值

  • 注意

await必须写在async函数中,但ssync函数中可以没有await
如果await的promise失败了,就会抛出异常,需要通过try…catch捕获处理

const fs = require('fs')
const util = require('util')
const mineReadFile = util.promisify(fs.readFile)

// 回调函数的方式都区三个文件拼接
// fs.readFile('./resource/content.txt',(err,data1)=>{
//     if(err) throw err
//     fs.readFile('./resource/c1.txt',(err,data2)=>{
//         if(err) throw err
//         fs.readFile('./resource/c2.txt',(err,data3)=>{
//             if(err) throw err
//             console.log(data1+data2+data3);
//         })
//     })
// })


// async与await
async function a() {
    try {
        let d1 = await mineReadFile('./resource/content.txt')
        let d2 = await mineReadFile('./resource/c1.txt')
        let d3 = await mineReadFile('./resource/c2.txt')
        console.log(d1 + d2 + d3);
    } catch (e) {
        console.log(e);
    }
}
a()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值