【Promise】第一部分 介绍Promise

本文详细介绍了Promise在JavaScript中的概念、使用场景,包括解决回调地狱、封装Ajax请求及文件读取,还展示了如何利用util.promisify简化回调函数。通过实例演示了Promise的链式调用和错误处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【Promise】第一部分 介绍Promise



1. 介绍Promise

1.1 什么是Promise?

  1. 抽象表达: Promise 是一门新的技术(ES6 规范),Promise 是 JS 中进行异步编程的新解决方案.

  2. 具体表达:

    从语法上来说: Promise 是一个构造函数;

    从功能上来说: promise 对象用来封装一个异步操作并可以获取其成功/ 失败的结果值.

1.2 为什么要使用Promise?

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

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

    什么是回调地狱?

    回调函数嵌套调用, 外部回调函数异步执行的结果是嵌套的回调执行的条件.

在这里插入图片描述

1.3 怎么使用Promise?

举几个例子:

第一个例子 需求是: 点击按钮,1s后弹窗是否中奖(中奖的概率是30%)

<body>
    <h2>Promise 抽奖</h2>
    <hr>
    <button>点击我进行抽奖</button>

    <script>
        const btn = document.querySelector('button')
        function random (max,min){
            return Math.floor(Math.random()*(max-min+1)+min)
        }
        btn.addEventListener('click',()=>{
            /* 
                resolve 成功
                reject  失败
            */
          // 创建一个实例化对象
            const p = new Promise((resolve,reject)=>{
                setTimeout(() => {
                    let n = random(1,100)
                    if(n > 30)
                    {
                        // 将Promise对象的状态设置为成功(可以传递参数)
                        resolve(n); 
                    }else{
                        // 将Promise对象的状态设置为失败(可以传递参数)
                        reject(n);       
                    }
                }, 1000);
            })
            p.then((value)=>{
                //成功的回调
                alert('很遗憾,您没有中奖!再接再厉!'+ value)
            },(reason)=>{
                //失败的回调
                alert('恭喜您,获得50W!!' + reason)
            })
        })
    </script>
</body>
</html>

第二个例子 读取文件

const fs = require('fs')

const p = new Promise((resolve, reject) => {
    fs.readFile('D:\\vs code\\Promise\\book.txt', (err, data) => {
        if (err) {
            reject(err)
        }
        resolve(data)
    })

})

p.then((value) => {
    console.log(value.toString());
}, (reason) => {
    console.log(reason);
})

第三个例子 发送Ajax请求

<body>
    <h2>Promise 请求</h2>
    <hr>
    <button>点击我发送请求</button>
    <script>
        const btn = document.querySelector('button')
        btn.addEventListener('click', () => {
            const p = new Promise((resolve, reject) => {
                // 创建对象
                const xhr = new XMLHttpRequest();
                // 设置响应体的类型
                xhr.responseType = 'json'
                //初始化
                xhr.open('Get', 'http://poetry.apiopen.top/sentences');
                //发送
                xhr.send();
                //处理响应的结果
                xhr.onreadystatechange = function () {

                    if (xhr.readyState === 4) {
                        //先判断响应状态码
                        if (xhr.status >= 200 && xhr.status < 300) {
                            resolve(xhr.response.result.name);
                        } else {
                            reject(xhr.status);
                        }
                    }
                }
            })
            p.then((value) => {
                console.log(value);
            }, (reason) => {
                console.log(reason);
            })
        })
    </script>
</body>


第四个例子 封装Ajax请求

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>promise</title>
</head>

<body>
    <script>
        function sendAjax(url) {
            return new Promise((resolve, reject) => {
                //创建对象
                const xhr = new XMLHttpRequest();
                //设置响应体类型
                xhr.responseType = 'json';
                //初始化
                xhr.open('Get', url);
                //发送
                xhr.send();
                //处理响应结果
                xhr.onreadystatechange = function () {
                    if (xhr.readyState == 4) {
                        if (xhr.status >= 200 && xhr.status < 300) {
                            resolve(xhr.response.result.name);
                        } else {
                            resject(xhr.status);
                        }
                    }
                }
            })
        }

        sendAjax('http://poetry.apiopen.top/sentences').then((value) => {
            console.log(value);
        }, (reason) => {
            console.log(reason);
        })
    </script>
</body>

</html>

第五个例子 封装fs读取文件

function miniReadyFile (path){
    return new Promise((resolve,reject)=>{
        const fs = require('fs')
        fs.readFile(path,(err,data)=>{
            if(err) 
            {
                reject(err);
            }
            resolve(data)
        })
    })
}

miniReadyFile('D:/vs code/Promise/book.txt')
.then((value)=>{ 
    console.log(value.toString());
},(reason)=>{
    console.log(reason);
})

1.4 util.promisify

在这里插入图片描述

上图来着nodejs官网,简单来说:我们可以使用该模块帮助我们去封装成一个函数,当我们去调用这个函数的时候返回的是一个Promise对象,但是使用的时候有条件:需要是以错误优先的回调风格的函数.

例如:1.3 中第四个例子里的 fs (err,data)=>{}

// 导入 util
const util = require('util')

// 导入 fs
const fs = require('fs')

// 返回一个函数,调用这个函数返回的是一个promise对象
let miniReady = util.promisify(fs.readFile);

miniReady('D:/vs code/Promise/book.txt').then((value)=>{
    console.log(value.toString());
},(reason)=>{
    console.log(reason);
})

总结

以上就是今天要讲的内容,希望对大家有所帮助!!!

### JavaScript 中的 Promise #### 创建 Promise 对象 在 JavaScript 中,`Promise` 是一种用于处理异步操作的对象。创建 `Promise` 实例时需传入一个执行器函数(executor),此函数接收两个参数:`resolve` 和 `reject` 函数[^3]。 ```javascript let promise = new Promise((resolve, reject) => { setTimeout(() => { resolve('Operation successful'); }, 2000); }); ``` 这段代码展示了如何通过设置定时器模拟耗时的操作,在两秒后调用 `resolve()` 来表示操作已完成并传递消息给后续链式调用的方法。 #### 处理成功与失败的结果 为了响应由 `Promise` 发起的任务状态变化,通常采用 `.then(onFulfilled, onRejected)` 方法来指定当承诺被兑现或拒绝后的回调逻辑[^1]。 对于上述例子而言: ```javascript promise.then( (value) => console.log(`Success: ${value}`), // 当 Promise 被解决(resolve)时触发 (reason) => console.error(`Error occurred: ${reason}`) // 如果发生异常(reject)则捕获这里 ); ``` 值得注意的是,`.then()` 的第一个参数是针对成功的场景而第二个则是用来捕捉可能发生的错误情况;当然也可以单独定义只关心某一方面的行为。 #### 错误传播机制 除了显式的调用 `reject(reason)` 抛出错误外,还可以利用 `throw` 关键字直接引发异常从而进入下一个最近的 `.catch()` 或者未指明拒绝处理器的 `.then(null, rejectionHandler)` 分支中去[^2]。 下面的例子说明了这一点: ```javascript const myPromise = new Promise((resolve, reject) => { console.log('Creating a promise instance...'); resolve('success message'); }); myPromise .then((value) => { console.log('Value:', value); return new Error('An error has been thrown'); // 这里可以替换为 throw new Error() }) .then((value) => { console.log(value); // 不会被打印因为上一步已经转到 catch 流程 }) .catch((error) => { console.warn('Caught an error:', error.message); }); ``` 在这个案例里面,尽管第一次的成功路径正常工作,但在第二次尝试继续链条的时候由于遇到了错误所以跳过了中间部分直接进入了最后的错误处理环节。 #### 并发执行多个 Promises 有时需要同时启动若干个独立但相互关联的任务,并希望等到全部完成后才采取下一步行动。这时就可以借助于静态方法 `Promise.all(iterable)` ,它接受一组可迭代对象作为输入参数,这些成员应当都是 `Promise` 类型实例。一旦所有内部项都完成了(无论是成功还是失败),整个集合也会随之改变其最终的状态[^4]。 ```javascript // 假设有三个不同的 API 请求或其他形式的异步任务 const taskOne = fetch('/api/data/one').then(response => response.json()); const taskTwo = fetch('/api/data/two').then(response => response.json()); const taskThree = fetch('/api/data/three').then(response => response.json()); // 同时发起这三个请求并将结果汇总在一起 Promise.all([taskOne, taskTwo, taskThree]) .then(([resultOne, resultTwo, resultThree]) => { console.table({ resultOne, resultTwo, resultThree }); }) .catch(error => console.error('At least one of the promises was rejected.', error)); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值