Promise学习(一)Promise是什么?怎么用?回调地狱怎么解决?


前言

    本文是通过尚硅谷老师的Promise教程阮一峰ES6教程来进行总结学习



Promise是什么

Promise概述

  Promise 是异步编程的一种解决方案,它是ES6 规范的一门新的技术。

  • 从语法上讲,promise是一个对象、也是一个构造函数,从它可以获取异步操作的消息。
  • 从本意上讲,它也是承诺,承诺会给你一个结果。
  • 从功能上来说: promise 对象用来封装一个异步操作并可以获取其成功/ 失败的结果值。

Promise的状态

promise实例有三种状态:

  • 异步操作未完成(pending
  • 异步操作成功(resolved / fulfilled
  • 异步操作失败(rejected

promise 的状态改变:

  1. pending 变为 resolved / fulfilled

  2. pending 变为 rejected

状态只能改变一次,一旦改变,就不会再变,且都会有一个结果数据,成功的结果数据一般称为 value, 失败的结果数据一般称为 reason

promise的基本流程

在这里插入图片描述

  代码展示如下,我们只调取了成功的回调,可以得到最后的结果为 ‘okk’

const p = new Promise((resolve, reject) => {
    // 异步语句 延时器
    setTimeout(() => {
        if ('异步操作成功') {
        	// 成功状态
            resolve('okk');
        } else {
        	// 失败状态
            reject('err');
        }
    },1000);
});

// 调用 then 方法 指定回调
p.then(value => {
	// 成功回调
    console.log(value);
}, reason => {
	// 失败回调
    console.log(reason);
});

    这里也要说一下改变 promise 状态和指定回调函数执行顺序,后续博客会系统的更新该部分问题,这里我们只需要知道只有当状态改变后才能得到数据,也就是说,当前状态由 pending 变为 resolved / fulfilled 后,才能得到成功的回调数据 ‘okk’ 。




为什么要用Promise

1. 指定回调函数的方式更加灵活

  • 旧的: 必须在启动异步任务前指定

  • promise : 启动异步任务 => 返回promie对象 => 给promise对象绑定回调函数(甚至可以在异步任务结束后指定/多个)

2. 支持链式调用, 可以解决回调地狱问题

2.1 什么是回调地狱

    回调地狱是指:多层嵌套函数,函数的返回值是下一个函数的执行条件。

setTimeout(() => {
   console.log('1');
   setTimeout(() => {
       console.log('2');
       setTimeout(() => {   
           console.log('3');
       }, 1000);
   }, 2000);
}, 3000);

在这里插入图片描述

回调函数中嵌套回调函数的情况就叫做回调地狱,可以看到,上面嵌套了三层延时器(也是一种回调函数),最后每隔一秒一次输出‘1’,‘2’,‘3’

回调地狱的缺点是不便于阅读 不便于异常处理

2.2 原生Promise链式解决方案

const test = n => {
    return new Promise((resolve, reject) => {
        // 异步任务
        setTimeout(() => {
            resolve(n);
        }, 1000);
    });
}

test(1).then(data => {
    console.log(data);
    return test(2);
}).then(data => {
    console.log(data);
    return test(3);
}).then(data => {
    console.log(data);
}).catch(data => {
    console.log(data);
});

2.3 Promise的async/await解决(终极方案)

const test1 = n => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(n)
        }, 1000);
    });
}

const test = async () => {
    console.log(await test1(1));
    console.log(await test1(2));
    console.log(await test1(3));
}
test();


Promise 的几个常用小案例

Promise 封装 fs 读取文件操作

/**
 * 封装一个函数 mineReadFile 读取文件内容
 * 参数:  path  文件路径
 * 返回:  promise 对象
 */
 
let mineReadFile = (path) => {
    return new Promise ((resolve, reject) => {
        //读取文件
        require('fs').readFile(path, (err, data) => {
            // 判断
            if (err) reject(err);
            // 成功
            resolve(data);
        });
    });
}

mineReadFile('./resource/content.txt').then(value => {
    // 输出文件内容(成功)
    console.log(value.toString());
}, reason => {
    console.log(reason);
});

Promise 的 util.promisify 方法

可以将函数直接变成promise的封装方式,不用再去手动封装

//引入 util 模块
const util = require('util');
//引入 fs 模块
const fs = require('fs');
//返回一个新的函数
let mineReadFile = util.promisify(fs.readFile);

mineReadFile('./resource/content.txt').then(value=>{
    console.log(value.toString());
}, reason=> {
    console.log(reason);
});

Promise 封装 Ajax 异步请求

/**
* 封装一个函数 sendAJAX 发送 GET AJAX 请求
* 参数   URL
* 返回结果 Promise 对象
*/
const sendAJAX = (url) => {
    return new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest();
        xhr.responseType = 'json';
        xhr.open('GET', url);
        xhr.send();
        // 处理结果
        xhr.onreadystatechange = () => {
            if (xhr.readyState === 4) {
                // 判断成功
                if(xhr.status >= 200 && xhr.status < 300) {
                    // 成功的结果为响应体
                    resolve(xhr.response);
                } else {
                    reject(xhr.status);
                }
            }
        }
    });
}

sendAJAX('https://pagead2.googlesyndication.com/getconfig/sodar?sv=200&tid=gda&tv=r20220718&st=env').then(value => {
    console.log(value);
}, reason => {
    console.log(reason);
})

本文中使用到的一些Promise的API(如 then, catch等方法)见下一篇博客
Promise学习(二)一篇文章带你快速了解Promise中的常用API

Authors: min
时间: 2022年7月24日

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值