返回顶部
首页 > 资讯 > 前端开发 > node.js >NodeJS中利用Promise来封装异步函数
  • 324
分享到

NodeJS中利用Promise来封装异步函数

函数NodeJSPromise 2022-06-04 17:06:46 324人浏览 薄情痞子
摘要

在写node.js的过程中,连续的io操作可能会导致“金字塔噩梦”,回调函数的多重嵌套让代码变的难以维护,利用Commonjs的Promise来封装异步函数,使用统一的链式api来摆脱多重回调的噩梦。  

在写node.js的过程中,连续的io操作可能会导致“金字塔噩梦”,回调函数的多重嵌套让代码变的难以维护,利用Commonjs的Promise来封装异步函数,使用统一的链式api来摆脱多重回调的噩梦。

  node.js提供的非阻塞IO模型允许我们利用回调函数的方式处理IO操作,但是当需要连续的IO操作时,你的回调函数会多重嵌套,代码很不美观,而且不易维护,而且可能会有许多错误处理的重复代码,也就是所谓的“Pyramid of Doom”。

step1(function (value1) {

    step2(value1, function(value2) {

        step3(value2, function(value3) {

            step4(value3, function(value4) {

                // Do something with value4

            });

        });

    });

});

  这其实就是Node.js的Control flow的问题,对于这个问题,解决方案都许多,比如利用async,或者eventProxy等,不过本文的主题是利用CommonJs规范中对Promise来解决这个问题。

什么是Promise?

  CommonJs的Promise规范有许多种,我们一般讨论的是Promise/A+规范,它定义了Promise的基本行为。

  Promise是一个对象,它通常代表一个在未来可能完成的异步操作。这个操作可能成功也可能失败,所以一个Promise对象一般有3个状态:Pending,Fulfilled,Rejected。分别代表未完成、成功完成和操作失败。一旦Promise对象的状态从Pending变成Fulfilled或者Rejected任意一个,它的状态都没有办法再被改变。

  一个Promise对象通常会有一个then方法,这个方法让我们可以去操作未来可能成功后返回的值或者是失败的原因。这个then方法是这样子的:

promise.then(onFulfilled, onRejected)
  显而易见的是,then方法接受两个参数,它们通常是两个函数,一个是用来处理操作成功后的结果的,另一个是用来处理操作失败后的原因的,这两个函数的第一个参数分别是成功后的结果和失败的原因。如果传给then方法的不是一个函数,那么这个参数会被忽略。

  then方法的返回值是一个Promise对象,这一个特点允许我们链式调用then来达到控制流程的效果。这里有许多细节上的问题,比如值的传递或者错误处理等。Promise的规范是这样定义的:

onFulfilled或者onRejected函数的返回值不是Promise对象,则该值将会作为下一个then方法中onFulfilled的第一个参数,如果返回值是一个Promise对象,怎么then方法的返回值就是该Promise对象
onFulfilled或者onRejected函数中如果有异常抛出,则该then方法的返回的Promise对象状态转为Rejected,如果该Promise对象调用then,则Error对象会作为onRejected函数的第一个参数
如果Promise状态变为Fulfilled而在then方法中没有提供onFulfilled函数,则then方法返回的Promise对象状态变为Fulfilled且成功的结果为上一个Promise的结果,Rejected同理。
  补充一句,onFulfilled和onRejected都是异步执行的。

规范的实现:q

  上面讲的是Promise的规范,而我们需要的是它的实现,q是一个对Promise/A+有着较好实现规范的库。

  首先我们需要创建一个Promise对象,关于Promise对象创建的规范在Promise/B中,这里不做详细的解释,直接上代码。

function(flag){

        var defer = q.defer();

        fs.readFile("a.txt", function(err, data){

        if(err) defer.reject(err);

            else defer.resolve(data);

            });

            return defer.promise;

    }

  多数Promise的实现在Promise的创建上大同小异,通过创建一个具有promise属性的defer对象,如果成功获取到值则调用defer.resolve(value),如果失败,则调用defer.reject(reason),最后返回defer的promise属性即可。这个过程可以理解为调用defer.resolve将Promise的状态变成Fulfilled,调用defer.reject将Promise的状态变成Rejected。

  在面对一系列连续的异步方法时,怎么利用Promise写出漂亮的代码呢?看下下面的例子。

promise0.then(function(result){

        // dosomething

        return result;

    }).then(function(result) {

        // dosomething

        return promise1;    

    }).then(function(result) {

        // dosomething

    }).catch(function(ex) {

        console.log(ex);

    }).finally(function(){

        console.log("final");

    });

  在上面的代码中,then方法只接受OnFulfilled,而catch方法实际上就是then(null, OnRejected),这样的话只要一系列异步方法只要始终是成功返回值的,那么代码就会瀑布式的向下运行,如果其中任意一个异步方法失败或者发生异常,那么根据CommonJs的Promise规范,将执行catch中的function。q还提供了finally方法,从字面上也很好理解,就是不论resolve还是reject,最终都会执行finally中的function。

  看上去似乎不错,代码更以维护且美观了,那么如果希望并发呢?

q.all([promise0, promise1, promise2]).spread(function(val0, val1, val2){

                    console.log(arguments);

                }).then(function(){

                    console.log("done");

                }).catch(function(err){

                    console.log(err);

                });

  q也为并发提供了api,调用all方法并传递一个Promise数组即可继续使用then的链式风格。还有像q.nfbind等可以将Node.js的原生API转化成Promise来统一代码格式也是挺好的。更多api在这里就不一一详述了。

结论

  本文主要介绍通过使用Promise来解决Node.js控制流问题,但Promise也可同样应用于前端,EMCAScript6已经提供了原生的API支持。需要指出的是Promise并不是唯一的解决方案,async也是一个很好的选择,并且提供更友好的并发控制API,不过我觉得Promise在封装具有异步方法的函数时更具优势。

好了,本文就先到这里了,希望对大家能够有所帮助。

--结束END--

本文标题: NodeJS中利用Promise来封装异步函数

本文链接: https://lsjlt.com/news/12243.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • NodeJS中利用Promise来封装异步函数
    在写Node.js的过程中,连续的IO操作可能会导致“金字塔噩梦”,回调函数的多重嵌套让代码变的难以维护,利用CommonJs的Promise来封装异步函数,使用统一的链式API来摆脱多重回调的噩梦。  ...
    99+
    2022-06-04
    函数 NodeJS Promise
  • Typescrip异步函数Promise使用方式
    目录Typescrip异步函数Promisetypescript- typescrip与react对象的类型数组类型函数类型类型断言内置对象泛型React 中使用Typescrip异...
    99+
    2024-04-02
  • Nodejs异步编程中的Promise有什么作用
    这篇文章主要介绍“Nodejs异步编程中的Promise有什么作用”,在日常操作中,相信很多人在Nodejs异步编程中的Promise有什么作用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,...
    99+
    2024-04-02
  • nodejs中有哪些async异步函数
    本篇文章给大家分享的是有关nodejs中有哪些async异步函数,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。async的集合控制:async...
    99+
    2024-04-02
  • 怎么利用promise及参数解构封装ajax请求
    这篇文章主要介绍怎么利用promise及参数解构封装ajax请求,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1.前端代码<!DOCTYPE html><html lang=&q...
    99+
    2023-06-08
  • nodejs async异步常用函数总结(推荐)
    nodejs框架类库很多,“流程控制”本来是件比较简单的事,但是对于nodejs的异步架构的实现方法,对于需要同步的业务逻辑,实现起来比较麻烦。 async的集合控制: async.map(arr, f...
    99+
    2022-06-04
    函数 常用 nodejs
  • C++ 函数异常处理中如何封装异常?
    c++++ 异常封装增强了代码的可读性和可维护性,可将错误信息与处理逻辑分离。通过定义继承自 std::exception 的异常类,可封装错误信息。使用 throw 抛出异常,用 tr...
    99+
    2024-04-15
    c++ 异常处理 标准库
  • golang函数如何利用goroutine实现异步编程?
    go 语言中使用 goroutine 实现异步编程。 goroutine 是一种轻量级线程,可以通过 go 关键字异步执行函数。 例如,在并发处理文件时,多个 goroutine 可以并...
    99+
    2024-05-02
    异步编程 golang
  • C++ 技术中的异常处理:如何使用异常类来封装异常信息?
    c++++异常处理机制允许封装异常信息,通过异常类从std::exception派生并使用throw抛出异常。该类提供what()方法获取错误消息,可用于在catch块中处理具体异常,提...
    99+
    2024-05-09
    c++
  • ASP中如何利用异步编程技术提高函数性能?
    ASP(Active Server Pages)是一种基于服务器端的动态网页技术,它可以通过服务器端脚本语言来动态生成 HTML 页面。在编写 ASP 程序时,我们经常会遇到一些需要执行较长时间的函数,例如数据库查询、文件上传等操作,这些操...
    99+
    2023-09-30
    异步编程 函数 shell
  • Node.js中如何使用异步Generator函数
    本篇文章给大家分享的是有关Node.js中如何使用异步Generator函数,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。HTTP 框架分类首...
    99+
    2024-04-02
  • 封装 Linux 系统调用中的 inb() 和 outb() 函数
    学习知识要善于思考,思考,再思考!今天编程网小编就给大家带来《封装 Linux 系统调用中的 inb() 和 outb() 函数》,以下内容主要包含等知识点,如果你正在学习或准备学习Golang,就...
    99+
    2024-04-04
  • Python中怎么使用装饰器来装饰函数
    在Python中,装饰器是一种函数,它接受一个函数作为参数,并返回一个新的函数。通过使用装饰器,可以在不修改原始函数代码的情况下添加...
    99+
    2024-03-12
    Python
  • Python 异步编程:如何利用 load 函数提高程序效率?
    在 Python 编程中,异步编程是一个非常重要的概念。它可以帮助我们提高程序效率,提高系统的吞吐量,并且可以让我们更好地利用系统资源。在本文中,我们将介绍 Python 异步编程的基础知识,并演示如何使用 load 函数来提高程序效率。...
    99+
    2023-10-17
    异步编程 编程算法 load
  • 如何在ASP中利用Spring接口实现异步数据同步?
    ASP是一种广泛使用的Web开发技术,而Spring则是一个非常流行的Java应用程序框架。在ASP中利用Spring接口实现异步数据同步可以有效提高系统的性能,让用户获得更好的体验。本文将介绍如何在ASP中利用Spring接口实现异步数据...
    99+
    2023-09-03
    同步 spring 接口
  • Django中怎么利用ajax异步刷新获取数据
    今天就跟大家聊聊有关Django中怎么利用ajax异步刷新获取数据,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。<script>   &nb...
    99+
    2023-06-04
  • 如何利用ASP 函数和异步编程技术优化numpy的使用?
    随着数据科学和机器学习的发展,NumPy成为Python中最受欢迎的数据科学库之一。然而,当数据集变得越来越大时,NumPy的执行速度可能会变慢,这可能会影响到数据分析和建模的效率。在本文中,我们将探讨如何利用ASP函数和异步编程技术来优化...
    99+
    2023-09-04
    函数 异步编程 numpy
  • vue中异步函数async和await的用法说明
    目录异步函数async和await用法async/await为什么叫异步外异内同异步函数async和await用法 先说一下async的用法,它作为一个关键字放到函数前面,用于表示函...
    99+
    2024-04-02
  • golang中封装模型的常用函数如何实现?
    在Golang中,封装模型的常用函数可以通过使用结构体和方法来实现。结构体是一种自定义的数据类型,可以用来封装相关的数据和方法。方法是与结构体关联的函数,可以在方法内部访问和操作结构体...
    99+
    2024-02-12
  • ASP 函数和异步编程:如何利用numpy实现高效数据处理?
    在当今这个数据驱动的世界中,高效的数据处理对于任何一个组织来说都至关重要。ASP 函数和异步编程是许多开发人员在数据处理中常用的工具,而 numpy 则是一个被广泛使用的 Python 库,它提供了许多强大的数据处理功能。在本文中,我们将...
    99+
    2023-09-04
    函数 异步编程 numpy
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作