美文网首页
JavaScript/Node.js异步函数的发展历史和基本使用

JavaScript/Node.js异步函数的发展历史和基本使用

作者: 小小奶狗 | 来源:发表于2018-06-28 14:29 被阅读24次

NodeJS学习咯

远古的ES5时代,让我们来简单模拟一下远古时代使用 chunk 回调函数处理异步时候,我们怎么操作 MongoDB数据库:

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 进行相应的显示或处理的。

时间来到了 ECMAScript2015 也就是ES6语法啦。ES6中提供了两种方案解决回调地狱:Promise和Generator。我们先来对比一下两者改写上面 mongoDB 插入数据的代码。(ES6同时提供的箭头函数也在这里试用一下)

let person = {name: "yika"};

mongoDb.open()
    .then(database => {
      return database.collection("users");
    })
    .then(collection => {
      return collection.insert(person);
    })
    .then(result => {
      console.log(result);
    })
    .catch(e => {
      throw new Error(e);
    })
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);
});

是不是发现了明显的不同,Promise 的写法还是存在嵌套,只不过看起来用链式调用掩盖了嵌套罢了,但起码 chuck 函数变成了 promise 函数,原本一层层包裹的金字塔变成了楼梯;而Generator迭代器则是利用 co 启动器模块, * 符和 yield 关键字,近乎真正的实现了异步代码风格同步化(仍有外层一次异步)。可是你有没有发现,这特么很不语义化啊,鬼知道 * 符和 yield 是干嘛用的,别急接着看。

在2017年末时候 ECMAScript2017也就是ES8中处理异步的方案加了个 async await,这也是当时

NodeJS7.x 中提出来的,实际上就是 generator 的语法糖,改造一下更健康,更语义化。代码如下:

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"});

是不是发现这变成了 PHP,JAVA,C/C++ 的同步编程风格,哈哈哈哈是的async就是这么强,而且目前这个模块已经加入 NodeJS 的内建模块中,使用前只需要引入 util.promisify即可。在Node真实项目中建议对 controller 层进行一级分层,专门建立 util 目录存放各模块中使用到的异步函数(同步写法),控制器中引入并调用函数即可。

既然async这么牛逼,我们具体怎么使用它呢?Server端的Node使用就不用多说了,内建模块。直接看Brower端吧,如果你使用了Webpack,那么只需要这样配置babel解析器即可:

module: {
    loaders: [
        {
            test: /\.js$/,
            exclude: /(node_modules|bower_components)/,
            loader: "babel",
            query: {
              presets: ['es2015', 'stage-3']
            }
        },
    ]
}

参考博客

  1. https://www.cnblogs.com/YikaJ/p/4996174.html

相关文章

网友评论

      本文标题:JavaScript/Node.js异步函数的发展历史和基本使用

      本文链接:https://www.haomeiwen.com/subject/fbtgyftx.html