node.js的几种异步控制的方法

本文介绍了Node.js中异步IO的四种控制方法:异步嵌套、事件监听、Promise及async模块。通过实例展示了如何使用这些方法进行异步操作,帮助读者更好地理解和掌握Node.js的异步编程。

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

      我们都知道异步IO是node.js的一大特色和优势,看了朴灵大大的深入浅出node.js的异步IO一章,还是觉得理解不够深入,但是学习是有过程的,万丈高楼平地起,多总结多实践就能提高。根据自己的学习经历,总结一下异步控制。

      方法1:

      通过异步嵌套来实现,例如:通过读取A.txt文件中的内容---B.txt,将其作为目标进一步去读取B.txt

var fs=require('fs');
fs.readFile('A.txt','utf8',function(err,data){ //读取出来是2进制形式的数据,所以要指定编码
    fs.readFile(data,'utf8',function(err,data){
        console.log(data)
    })
})
      方法2:

      通过事件监听的方式来进行异步控制。Node.js 所有的异步 I/O 操作在完成时都会发送一个事件到事件队列。Node.js里面的许多对象都会分发事件:一个net.Server对象会在每次有新连接时分发一个事件, 一个fs.readStream对象会在文件被打开的时候发出一个事件。 所有这些产生事件的对象都是 events.EventEmitter 的实例。

var event=require('events');
var eventMitter=new event;
var fs=require('fs');
var eventMitter=new event;
eventMitter.on('start',function(data){
    fs.readFile(data,'utf8',function(err,data){
        console.log(data);
    })
});
fs.readFile('A.txt','utf8',function(err,data){
    eventMitter.emit('start',data);
});
    
     方法3:

    Promise。它表示一个异步操作的最终结果 。相当于:服务员下单后去干别的,做好后会端饭,promise是承诺,做好后可能还会做一些其他处理。

//这是一个需要延迟处理的任务
var Defer = function(){
    var status = 'pending';//初始态
    var value;//异步操作的最终的值
    var callback;//异步操作成功后的回调
    return {
        //当调用resolve的时候就表示成功了
        //异步操作完成之后调用,表示操作成功了
        resolve:function(_value){
            value = _value;
            status = 'resolve';
            callback(value);
        },
        //就是承诺的对象,它会返回给客户端
        promise:{
            then:function(_callback_){
                callback = _callback_;
            }
        }
    }
}

var defer = Defer();
var fs = require('fs');
fs.readFile('1.txt','utf8',function(err,data){
    defer.resolve(data);//读取文件完成后调用resolve把状态改为成功
})

var promise = defer.promise;
//defer给你一个承诺,当异步操作完成之后我会调用你传给我回调函数
promise.then(function(data){
    console.log(data);
});
           方法4:

        使用async模块,这是一个非常强大的模块。下面是它的几种常用方法的实例:

        series方法:串行执行异步任务,cb函数相当于express框架中的配置对象app中的next函数。当cb的第一error参数有值时,则不往下执行下一个函数,直接到series的回调函数处。

<pre name="code" class="javascript">var async=require('async');
async.series([
    function(cb){
        setTimeout(function(){
            console.log('看电视');
            cb(null,'看电视');
        },3000);
    },
    function(cb){
        setTimeout(function(){
            console.log('写作业');
            cb(null,'做作业');
        },3000);

    }

],function(err,result){
    console.log(err);
    console.log(result);
})

      执行结果:

        

     ②parallel方法:并行执行。比如同时获取数据和渲染模板,就是此方法的应用场景。

var async=require('async');
async.parallel([
    function(cb){
        setTimeout(function(){
            console.log('看电视');
            cb(null,'看电视');
        },3000);
    },
    function(cb){
        setTimeout(function(){
            console.log('写作业');
            cb(null,'做作业');
        },3000);

    }

],function(err,result){//当上面两个异步任务 执行完后执行的回调
    console.log(err);
    console.log(result);
})

       执行结果:

        

       ③waterfall方法:

//waterfall:是串行的,但是每个函数产生的返回值会传递给第二个函数
var async=require('async');
async.waterfall([
    function(cb){
        setTimeout(function(){
           //console.log(data);
            cb(null,'看电视');
        },1000);
    },
    function(data,cb){
        setTimeout(function(){
            //console.log(data)
            cb(null,data+'做作业');
        },1000);
    },
    function(data,cb){
        setTimeout(function(){
            cb(null,data+'睡觉');
        },1000);
    }
],function(err,result){//当上面两个异步任务 执行完后执行的回调
    console.log(err);
    console.log(result);
})
      执行结果:

                 

       ④foreach方法:

var async=require('async');

var arr=[1,2,3];
//串行迭代,并在迭代完成后执行回调
console.time('cost')
/*
async.eachSeries(arr,function(item,cb){
    setTimeout(function(){
        console.log(item);
        cb();
    },1000)
},function(){
    console.timeEnd('cost')
});
*/
//同时执行,并行迭代
async.forEach(arr,function(item,cb){
    setTimeout(function(){
        console.log(item);
        cb();
    },1000)
},function(){
    console.timeEnd('cost')
});
     ⑤auto方法:并行和串行执行都有时,举例

var async=require('async');

async.auto({
    mix:['water','flour',function(results,cb){
        //console.log(arguments)
        //console.log(results);
        cb(null,results.water+'+'+results.flour);
    }],
    steam:['mix',function(results,cb){
        cb(null,results.mix+'+'+'蒸')
    }],
       water:function(sb){
           console.time('cost')
           sb(null,'水')
           //console.log('1')
       },
       flour:function(cb){
           cb(null,'面粉')
       },
    //定义依赖关系,results是个对象

    }, function(err,result){//result是个对象
    console.timeEnd('cost')
    console.log(result);
});
      执行结果:  

                           







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值