NodeJs通过async和await处理异步的方法

我们在编写express后台,经常要有许多异步io的处理。在远古时代,我们都是用chunk函数处理,也就是我们最熟悉的那种默认第一个参数是error的函数。我们来模拟一个mongo数据库的操作,感受一下。

本文主要介绍NodeJs通过async/await处理异步的方法,内容挺不错的,现在分享给大家,也给大家做个参考,希望能帮助到大家。

mongoDb.open(function(err, db){  if(!err){    db.collection("users", function(err, collection){      if(!err){        let person = {name: "yika", age: 20};        collection.insert(person, function(err, result){          if(!err){            console.log(result);          }        });      }    })  }});

登录后复制

这个也就是被我们所诟病的callback hell,一堆横向金字塔,如果将回调拆分成函数,则会变得非常支离破碎。为了防止到恶心到大家,我甚至没有写关于错误的处理,正常来说,每一个异步的操作都需要都它的error进行相应的显示或处理的。

Promise时代

后来进入了好一点的时代就是Promise,我们也可以称作链式操作。关于Promise,我也是之前有专门写过一系列的博文,有兴趣可以回头翻一下。这里来看看,将以上改写之后的状况。

let person = {name: "yika"};mongoDb  .open()  .then(function(database){   return database.collection("users");  })  .then(function(collection){   return collection.insert(person);  })  .then(function(result){   console.log(result);  })  .catch(function(e){   throw new Error(e);  })

登录后复制

我们可以看到,我们将金字塔已经平铺成一条线状结构了。相比之前恶心难以维护的chunk函数,变成了promise函数,并且错误的处理也变得十分优雅。但是我们仍然不可忽视某些问题,例如我们必须忍受各个逻辑被一个又一个的then()包裹起来,每一个函数都有其独立的作用域,如果为了共享某个数据就必须挂在最外层,最重要的还是,它与我们熟悉的同步编程仍然有差别。

Generator时代

TJ大神,借着ES6的Generator迭代器,最早实现了异步编程同步化的功能,也就是最为我们所熟知的co库。我们通过co(function *(){})可以使函数内部通过迭代器来控制。而co在这里则是充当了启动器的角色。关于Generator和co我在之前的博文也同样说过。

let co = require("co");co(function *(){  let db, collection, result;   let person = {name: "yika"};  try{    db = yield mongoDb.open();    collection = yield db.collection("users");    result = yield collection.insert(person);  }catch(e){    console.error(e.message);  }  console.log(result);});

登录后复制

我们已经非常接近同步编程了,在co包裹的函数内部,只有一个异步执行完毕,才会继续执行下面的代码。并且错误的处理也是通过try and catch进行实现的。不过我们不得不承认的是,迭代器终究不是为异步而存在的。里面的yield和*的语义也并不代表的就是异步函数标志。并且迭代器是需要co去驱动的,它和我们想象中的函数多少有一点点不同。

async/await时代

我们关注到ES7的async/await,才发现这才是我们想要的!我们将上面的代码小小改写一下。

async function insertData(person){  let db, collection, result;   try{    db = await mongoDb.open();    collection = await db.collection("users");    result = await collection.insert(person);  }catch(e){    console.error(e.message);  }  console.log(result);} insertData({name: "yika"});

登录后复制

我们可以看到inserData是一个真正的函数,是我们可以直接去调用而无需启动器驱动的。当然内部我们也可以感受到处理yield变成了await以外,并没有很大区别。async/await,更符合我们异步编程的语义。

那么问题来了,how to use it?

使用

我们一开始就说过,babel已经支持async的transform了,所以我们使用的时候引入babel就行。当然server端和browser端,可以有不同的处理方法。在开始之前我们需要引入以下的package,preset-stage-3里就有我们需要的async/await的编译文件。

$ npm install babel-core --save$ npm install babel-preset-es2015 --save$ npm install babel-preset-stage-3 --save

登录后复制

Browser端

Babel一开始的出现就是为了让旧浏览器也能支持新的ES6特性,提升我们的开发体验。所以在Babel一开始就是可以通过babel-cli终端进行编译的。或者引入babel文件在浏览器端进行编译。当然这些都不是我最推荐的,所以我就带过不说啦。在前端静态资源配置里,webpack是现在比较好的解决方案,它支持静态资源的模块依赖,打包合并,还有语言的预处理,当然在这里我们就是指babel的处理。

// webpack.config.js// 省略上面的文件输入输出的配置,直接看模块加载器的配置module: {  loaders: [    {      test: /.js$/,      exclude: /(node_modules|bower_components)/,      loader: "babel",      query: {       presets: ['es2015', 'stage-3']      }    },  ]}

登录后复制

这样我们就可以愉快的使用了。

Server端

相对来说,后端比前端需要处理的异步IO地方多得多,也是更加需要这个。那我们在Server端又如何引入babel呢?

其实最简单也是最麻烦的方法就是,直接把js文件通过babel编译出新的文件再来使用。当然也就免不了冗余文件了,眼不见心不烦,还是换一个方法吧。

我们使用官方提供的require hook方法,顾名思义就是通过require进来后,接下来的文件进行require的时候都会经过Babel的处理。因为我们知道CommonJs是同步的模块依赖,所以也是可行的方法。我们需要多一个用于启动的js文件,一个真正执行程序的js文件。

// index.js // 用于引入babel,并且启动app.jsrequire("babel-core/register");require("./app.js");

登录后复制

配置完hook之后,我们就配置babel的.babelrc文件,它是一个json格式的文件。es2015看情况配置,如果是已经是Node5.0版本,就无需再进行编译。

{ "presets": ["stage-3", "es2015"]}

登录后复制

最后我们的异步函数代码,写在app.js里即可。

相关推荐:

小程序开发之利用co处理异步流程的实例教程

小程序开发之利用co处理异步流程的实例教程

小程序开发之利用co处理异步流程的实例教程

以上就是NodeJs通过async和await处理异步的方法的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2788890.html

(0)
上一篇 2025年3月8日 18:32:46
下一篇 2025年2月26日 15:46:17

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • 细说AngularJS的控制器函数

    前面我们和大家分享过angularjs学习之控制器、数据绑定、作用域详解,本文我们主要介绍angularjs中控制器函数的定义与使用方法,结合具体实例形式分析了angularjs控制器函数的定义、绑定及相关使用技巧,需要的朋友可以参考下,希…

    2025年3月8日
    200
  • JS合并json对象实例

    我们分享过很多关于json对象的文章,本文主要介绍js实现合并json对象的方法,涉及javascript递归调用与json格式数据遍历的相关操作技巧,需要的朋友可以参考下,希望能帮助到大家。 一、问题: 求json对象合并的方法 var …

    2025年3月8日
    200
  • form转json实现方法

    本文主要介绍了jquery实现的form转json功能,结合完整实例形式分析了jquery将form表单数据封装成json传输的具体步骤与相关操作技巧,需要的朋友可以参考下,希望能帮助到大家。 nbsp;html PUBLIC “-//W3…

    2025年3月8日
    200
  • JS实现websocket实时消息提示

    本文主要介绍了js实现websocket长轮询实时消息提示的效果的相关资料,需要的朋友可以参考下,希望能帮助到大家。 效果图如下: 参考代码如下: jsp代码:             “>”  style=”max-width:90…

    2025年3月8日
    200
  • JavaScript中出现的错误处理方式

    javascript的事件驱动范式增添了丰富的语言,也是让使用javascript编程变得更加多样化。如果将浏览器设想为javascript的事件驱动工具,那么当错误发生时,某个事件就会被抛出。理论上可以认为这些发生的错误只是javascr…

    2025年3月8日
    200
  • seajs中常用的几个功能和配置

    本文主要介绍了seajs中最常用的7个功能、配置,结合实例形式简单分析了seajs中常用的项目配置、模块加载、定义、获取等操作技巧,需要的朋友可以参考下额,希望能帮助到大家。 1. seajs.config seajs.config({ /…

    编程技术 2025年3月8日
    200
  • 怎么使用SeaJS中use函数

    有了 define 等模块定义规范的实现,我们可以开发出很多模块。但光有一堆模块不管用,我们还得让它们能跑起来。在 seajs 里,要启动模块系统很简单: seajs.use(‘./main’); 登录后复制登录后复制 seajs.use …

    编程技术 2025年3月8日
    200
  • JS常用截取字符串方法合集

    js中的字符串不管是在我们的实际开发中还是在日常练习中都是一种很长用的数据类型,而我们会经常的遇到需要的js字符串中少个后缀或者多个后缀,这就需要对字符串进行操作了,我们来看看字符串的截取方法吧!如何将字符串中多余的部分截取掉! 我们使用函…

    编程技术 2025年3月8日
    200
  • vue.js将echarts封装为组件一键使用

    做项目的时候为了让数据展示的更加直观,总会用到图表相关的控件,而说到图表控件第一时间当然想到echarts这个开源项目,而它不像iview、element-ui这些组件使用起来那么便捷,需要绕一个小弯,为了图方便于是对echarts进行了一…

    2025年3月8日
    200
  • seajs中模块依赖加载处理实例分析

    本文主要介绍了seajs中模块依赖的加载处理,结合实例形式分析了seajs模块依赖与加载的原理、相关注意事项与使用方法,需要的朋友可以参考下,希望能帮助到大家。 最近在做项目的时候发现一些关于模块依赖问题,特记录下: 比如现有3个文件: /…

    编程技术 2025年3月8日
    200

发表回复

登录后才能评论