Promises原理及实现

一、Promise基本概念

Promise 是异步编程的一种解决方案,用于处理异步操作。ES6 的 Promise 规范,是对异步编程的一种规范化,使得编写和维护异步程序更加容易、直观。

Promise 是一个对象,它代表了一个异步操作的最终结果。它可以是下列三种状态之一:等待态(pending)、完成态(fulfilled)、拒绝态(rejected)。

Promise 的优点在于可以避免“回调地狱”,使得代码结构清晰,更具有可读性和可维护性。

二、Promise基本用法

ES6 新增了 `Promise` 构造函数,可以使用 `new Promise()` 来创建一个 Promise 对象。

    
        let promise = new Promise(function(resolve, reject){
            //异步操作的代码
            //成功时调用 resolve()
            //失败时调用 reject()
        })
    

当 Promise 对象的状态发生改变时,会产生对应的回调函数。可以使用 `promise.then()` 方法来指定 Promise 对象状态变为 fulfilled 或 rejected 时调用的回调函数。这两个方法都返回一个新的 Promise 对象,可以进行链式调用。

    
        let promise = new Promise(function(resolve, reject){
            setTimeout(() => resolve("异步操作成功"), 1000);
        })

        promise.then(res => {
            console.log(res); //异步操作成功
        })
    

三、Promise原理

Promise 的基本原理就是对异步操作进行封装,使其可以返回一个 Promise 对象,并可以使用链式调用方法。

我们可以手动模拟一下 Promise 的内部实现:

    
        function Promise_old(fn){
            let state = 'pending';
            let value = null;
            let callbacks = [];

            this.then = function(onFulfilled){
                return new Promise_old(function(resolve){
                    handle({
                        onFulfilled: onFulfilled || null,
                        resolve: resolve
                    })
                })
            }

            function handle(callback){
                if(state === 'pending'){
                    callbacks.push(callback);
                    return;
                }

                if(!callback.onFulfilled){
                    callback.resolve(value);
                    return;
                }

                let ret = callback.onFulfilled(value);
                callback.resolve(ret);
            }

            function resolve(newValue){
                if(newValue && (typeof newValue === 'object' || typeof newValue === 'function')){
                    let then = newValue.then;
                    if(typeof then === 'function'){
                        then.call(newValue, resolve);
                        return;
                    }
                }

                setTimeout(function(){
                    state = 'fulfilled';
                    value = newValue;
                    callbacks.forEach(function(callback){
                        handle(callback);
                    })
                }, 0);
            }

            fn(resolve);
        }
    

上述代码中,我们定义了 `Promise_old` 构造函数。它内部定义了 `state`、`value`、`callbacks` 三个变量,分别记录 Promise 对象的当前状态、结果值和对应回调函数数组。同时我们定义了 `then` 方法,可以使用链式调用,将传入的回调函数压入 `callbacks` 数组中。

关键的 `handle` 函数则利用了 JavaScript 的事件循环机制,当 Promise 对象的状态从 `pending` 改变时,依次执行队列中的回调函数。

最后通过 `resolve` 函数,可以修改 Promise 对象的状态,触发对应回调函数的执行。

四、Promise实例应用

1、串行异步任务的处理

使用 `Promise` 可以让多个异步任务按顺序执行,比如读取多个文件,顺序进行操作。这里我们演示一个例子,读取两个文件,分别将其内容存放在一个数组中。

    
        let fs = require('fs');

        function readFile(filename){
            return new Promise(function(resolve, reject){
                fs.readFile(filename, 'utf8', function(err, data){
                    if(err){
                        reject(err);
                        return;
                    }
                    resolve(data);
                })
            })
        }

        Promise.all([
            readFile('file1.txt'),
            readFile('file2.txt')
        ]).then(function(dataArr){
            console.log(dataArr); //[data1, data2]
        })
    

2、并发异步任务的处理

有时候需要同时执行多个异步任务,可以使用 `Promise.all()` 方法,将返回值存放在数组中按顺序返回。

    
        let dataArr = [];

        function fetchData(url){
            return new Promise((resolve, reject) => {
                fetch(url)
                .then(res => res.json())
                .then(data => {
                    dataArr.push(data);
                    resolve(data);
                })
                .catch(error => reject(error))
            })
        }

        Promise.all([
            fetchData('https://api.xxx.com/1'),
            fetchData('https://api.xxx.com/2'),
            fetchData('https://api.xxx.com/3')
        ]).then(() => {
            console.log(dataArr); //[data1, data2, data3]
        })
    

3、Promise异常处理

使用 `then()` 方法时,可以链式调用多个回调函数,并在其中任何一个回调函数中引发错误,就会被 `catch()` 方法捕获。如果在 `then()` 方法中不使用回调函数,就必须在链头使用 `catch()` 方法来进行异常处理。

    
        function fetchData(){
            return new Promise((resolve, reject) => {
                //使用 Math.random() 模拟程序执行时出现错误
                if(Math.random() > 0.5){
                    resolve('fetch data success');
                } else {
                    reject('fetch data failed');
                }
            })
        }

        //这个方法捕获了两个 Promise 对象中的异常,并输出错误信息
        fetchData().then(res => {
            console.log(res);
        }).catch(error => {
            console.log(error);
        })
    

结束语

Promise 是异步编程的一种新规范,提高了代码的可读性、可维护性和稳定性。通过上述的介绍和实例,希望读者能够深入了解 Promise 的基本原理和使用方法,高效编写异步代码。

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/154561.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2024-11-16 14:12
下一篇 2024-11-16 14:12

相关推荐

  • Harris角点检测算法原理与实现

    本文将从多个方面对Harris角点检测算法进行详细的阐述,包括算法原理、实现步骤、代码实现等。 一、Harris角点检测算法原理 Harris角点检测算法是一种经典的计算机视觉算法…

    编程 2025-04-29
  • 瘦脸算法 Python 原理与实现

    本文将从多个方面详细阐述瘦脸算法 Python 实现的原理和方法,包括该算法的意义、流程、代码实现、优化等内容。 一、算法意义 随着科技的发展,瘦脸算法已经成为了人们修图中不可缺少…

    编程 2025-04-29
  • 神经网络BP算法原理

    本文将从多个方面对神经网络BP算法原理进行详细阐述,并给出完整的代码示例。 一、BP算法简介 BP算法是一种常用的神经网络训练算法,其全称为反向传播算法。BP算法的基本思想是通过正…

    编程 2025-04-29
  • GloVe词向量:从原理到应用

    本文将从多个方面对GloVe词向量进行详细的阐述,包括其原理、优缺点、应用以及代码实现。如果你对词向量感兴趣,那么这篇文章将会是一次很好的学习体验。 一、原理 GloVe(Glob…

    编程 2025-04-27
  • 编译原理语法分析思维导图

    本文将从以下几个方面详细阐述编译原理语法分析思维导图: 一、语法分析介绍 1.1 语法分析的定义 语法分析是编译器中将输入的字符流转换成抽象语法树的一个过程。该过程的目的是确保输入…

    编程 2025-04-27
  • Python字典底层原理用法介绍

    本文将以Python字典底层原理为中心,从多个方面详细阐述。字典是Python语言的重要组成部分,具有非常强大的功能,掌握其底层原理对于学习和使用Python将是非常有帮助的。 一…

    编程 2025-04-25
  • Grep 精准匹配:探究匹配原理和常见应用

    一、什么是 Grep 精准匹配 Grep 是一款在 Linux 系统下常用的文本搜索和处理工具,精准匹配是它最常用的一个功能。Grep 精准匹配是指在一个文本文件中查找与指定模式完…

    编程 2025-04-25
  • 深入探讨冯诺依曼原理

    一、原理概述 冯诺依曼原理,又称“存储程序控制原理”,是指计算机的程序和数据都存储在同一个存储器中,并且通过一个统一的总线来传输数据。这个原理的提出,是计算机科学发展中的重大进展,…

    编程 2025-04-25
  • 朴素贝叶斯原理详解

    一、朴素贝叶斯基础 朴素贝叶斯是一种基于贝叶斯定理的算法,用于分类和预测。贝叶斯定理是一种计算条件概率的方法,即已知某些条件下,某事件发生的概率,求某条件下另一事件发生的概率。朴素…

    编程 2025-04-25
  • 单点登录原理

    一、什么是单点登录 单点登录(Single Sign On,SSO)指的是用户只需要登录一次,在多个应用系统中使用同一个账号和密码登录,而且在所有系统中都可以使用,而不需要在每个系…

    编程 2025-04-25

发表回复

登录后才能评论