JS中的Promise对象

前言

  本质是一个类:Promise(翻译:承诺;保证)
  创建对象:new Promise时,传的函数叫执行器 这个执行器是立即执行的
  作用:promise是为了让你更加优雅写异步代码,避免回调地狱。

回调地狱
  回调地域,表示回调函数中嵌套回调函数。
  利用回调函数实现异步有什么不足如果层数非常多,就会出现回调地域,代码的可读性不好。

创建出来的promise对象有三个状态:
         1)默认情况下,处于pending状态   pendding是等待
         2)成功状态,fulfilled
         3)失败状态,rejected
注意:       
  1)处理等待状态的promise,要么转化成成功状态的promise,要么转化成失败的promise。不可能既成功又失败。
  2)如果一个promise从等待转化成了成功状态,就不可以再转化成失败状态。
  3)如果一个promise从等待状态转化成了失败状态,就不可能再转化成成功的状态。

1 终值(resolve)和拒因(reject)

在执行器中,有两个参数,一个resolve,一个叫reject:

  • resolve翻译:解决;决心):调用 resolve 以让promise对象从等待状态变成成功状态,调用resolve,可以传递一个终值(value)
  • reject翻译:拒绝):调用 reject 可以让promise从等待状态变成失败状态,调用reject,可以传递一个拒因(reason)

new Promise时,传的函数叫执行器 这个执行器是立即执行的。

let p1 = new Promise(function(resolve,reject){//两个参数
    // "包包"叫终值   成功的结果
    // resolve("包包")
// 一旦成功了,就不能再转成失败态
    // "没钱"叫拒因   失败的结果
    reject("没钱");
});
// console.log(p1);  // Promise { <pending> }  pending是等待的意思
// console.log(p1); // Promise { '包包' }
console.log(p1);  // Promise { <rejected> '没钱' }

2 then

  在promise对象上有一个方法,叫then,then这个方法中,可以传递两个函数。
  只有promise对象才能.then

then方法的第一个参数是resolved状态的回调函数,第二个参数(可选)是rejected状态的回调函数。
  • 如果promise对象从等待到成功状态,就会调用then中的第1个方法,方法的第1个参数就表示终值。
  • 如果promise对象从等等到失败状态,就会调用then中的第2个方法,方法的第1个参数就表示拒因。

then方法是定义在原型对象Promise.prototype上的。在这里插入图片描述

代码如下:

let p1 = new Promise(function(resolve,reject){
    // 一旦成功了,就不能再转成失败态
    // resolve("包包")
    // reject("没钱");
    console.log("我是否是立即执行");
});
p1.then(function(value){
    console.log(value);  // value叫终值  成功的结果
},function(reason){
    console.log(reason);  // reason叫拒因   失败的结果
});

利用Promise解决异步问题: &emsp;&emsp;当我们new Promise时,可以就在执行器中写异步代码。 &emsp;&emsp;简单使用promise解决异步问题。

const fs = require("fs");
// 一般是使用Promise去包含异步代码
let p1 = new Promise(function(resolve,reject){
    // 在执行器中写异步代码
    fs.readFile("./nn.txt","utf-8",function(err,data){
        if(err){
            reject(err)
        }else{
            resolve(data);//这里就可以拿到nn.txt中的数据
        }
    })
})
p1.then(function(value){ console.log(value); },function(reason){ console.log(reason); })

封装读取文件的promise方法。

// 封装一个函数,此函数返回promise对象
const fs = require("fs");
function readFile(filename){
    return new Promise(function(resolve,reject){
        // 异步代码写在执行器中
        fs.readFile(filename,"utf-8",function(err,data){
            if(err){
                reject(err)
            }else{
                resolve(data)
            }
        })
    })
}
readFile("./nn.txt").then(value=>console.log(value),reason=>console.log(reason))

在很多模块,都是别人封装的方法,直接返回promise对象
所以,碰见莫名其妙.then的对象,就要看看它本身是不是封装好的。

const fs = require("fs").promises;  // 引入fs模块的promise版本
fs.readFile("./nn.txt","utf-8").then(data=>console.log(data))

3 then链

  then是一个函数调用 只要是函数调用,就有返回值。then的返回值也是一个promise

  它返回的promise是处于什么状态,是由p1.then 中的两个函数决定的
  下一个.then中是走成功的回调函数,还是走失败的回调函数,取决于你上一个.then中的两个函数中做了啥。
   p1.then中不管是哪个方法执行,只要不报错,新的promise就会转成成功态(从等待状态转成成功态)。

终值:看此方法返回的结果 没有返回结果 返回und und就会作为终值

let p1 = new Promise((resolve,reject)=>{
    resolve("包包")
})

p1.then(value=>{   //resolve
    console.log(value);  // 包包
},reason=>{        //reject
    console.log(reason);
}).then(value=>{
    console.log(value);  // undefined 
},reason=>{
    console.log(reason);
})

Promise 是一个类 函数 函数也是对象
Promise.resolve(); 表示直接创建出一个成功的promise
Promise.reject(); 表示直接创建出一个失败的promise

let p1 = Promise.resolve("包包");
// .then时,可以不写第2个函数
p1.then(value=>{console.log(value);})

测试例题:

new Promise((resolve,reject)=>{
    setTimeout(()=>{
        resolve(10)      
    },2000)
}).then(value => {
    console.log(value)   // 10
    return value * n;    // 报错了,会走下一个then的第2个函数
},reason => {
    console.log(reason)
    return Promise.reject(666);
}).then(value => {
    console.log(value)
},reason => {
    console.log(reason); // n is not def
    return reason * 10;  //return NaN 没有报错
}).then(value => {
    console.log(value)   // NaN
    return Promise.reject(value * 100)// 返回一个失败状态的promise 返回的结果在下面
},reason => {
    console.log(reason)
}).then(value=>{

},reason => {
    console.log(reason)            // NaN
})
// 10   n is not def  NaN   NaN

4 then的顺延和async和await的使用

  第1个.then中没有失败的回调 它会继续在下一个then中找失败的回调函数 如果还找不到 继续向下找。
这种情况叫做then顺延

let p1 = new Promise((resolve,reject)=>{
    reject("没钱")
})
p1.then(value=>{    ==========这个then相当于只有value终值
    console.log(value);
}).then(value=>{
    console.log(value);
},reason=>{
    console.log(reason);=========一直找到出现拒因的then为止,这叫顺延
    
}).then(null,reason=>{ ==========这个then相当于只有reson拒因
    console.log(reason);

4.1 .catch语法糖

一般情况下,在then中只写一个成功的回调。
.catch.then的语法糖,里面放失败的回调。

p1.then(value=>{
    console.log(value);
}).catch(reason=>{
    console.log("xx:"+reason);
})

4.2 async和await的使用(只能返回成功的结果)

  async 可以修改一个函数;如果使用async修饰了一个函数,这个函数就会返回一个promise。
  async+await就是promise的语法糖 用的非常多。

一般情况下,在async修饰的函数内部,会出现一个await

  1. 要用await,必须要使用async(否则报错)。
  2. async可以不使用awaitasync可以单独存在)。
  3. await后面通常是跟一个promise
  4. await后面的代码,相当于放到了一个then中,then中的第1个函数中。
  5. await返回值是成功的结果,失败的结果需要通过try catch来获取。
let p1 = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        reject("没钱")
    },2000)
})
==========================================================================================
async function fn() {
    // await返回值是成功的结果
    let value = await p1; // await后面跟promise 要使用await 对应的函数必须是async函数
    console.log(value);
}
fn();

4.3 try catch finally(能够返回失败的结果)

语法:

try {
    tryCode - 尝试执行代码块
}
catch(err) {
    catchCode - 捕获错误的代码块
}
finally {
    finallyCode - 无论 try / catch 结果如何都会执行的代码块
}
  1. 不管有没有异常,finally中的代码都会执行
  2. trycatch中有return时,finally中的代码依然会继续执行
  3. finally是在return后面的表达式运算之后执行的,此时并没有返回运算之后的值,而是把值保存起来,不管finally对该值做任何的改变,返回的值都不会改变,依然返回保存起来的值。也就是说方法的返回值是在finally运算之前就确定了的。
  4. finally代码中最好不要包含return,程序会提前退出,也就是说返回的值不是try或catch中的值。(引用地址:传送门)
async function fn(){
    console.log("start");   
    // await 前面只能获取成功的结果,不能获取失败的结果
    // 要获取失败的结果,可以使用try catch
    // try中放可能会失败的代码
    try{
        let value = await p1; // value就是终值,成功的结果  await本意是等待    等待p1变成功
    }catch(reason){  // 失败的结果,需要在catch中捕获 catch是捕获的意思
        console.log(reason);
    }finally{
    console.log("不管是成功还是失败,finally中的代码都会走")
    }
    console.log(value);
}
fn()
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值