关闭

nodejs中异步回调总有些不完美

标签: nodejsjs
374人阅读 评论(0) 收藏 举报
分类:

nodejs借助于node运行环境而实现的一个比较灵巧的前后一体化的开发环境,随比不了php,python,但是在快速开发维护的时间成本上,node一骑绝尘。node自身由衷的想法,花最小的硬件成本,追求更高的并发,更高的处理性能。

nodejs是一个让javascript运行在服务端的开发平台,它让javascript的触角伸到了服务器,可以与php,jsp,python,ruby平起平坐


node的与众不同之处:

1.node.js不是一门独立的语言,与php,jsp,python, perl,ruby的"既是语言,也是平台"不同,node.js的使用javascript进行编程,运行在chrom的v8引擎之上。它自己不用建设在任何的服务器软件之上。


node特点:

1.单线程

2.非阻塞

3.事件驱动

首先,node不为每一个用户开辟一个线程,所以非常极端的选择了单线程。单线程,要照顾好所有的用户,那么就必须有非阻塞I/O,否则一个人的I/O就把别人,自己的都给阻塞了。一旦有了非阻塞的I/O,一个人如果I/O去了,就会放弃CPU的使用权,换成另一个人使用CPU(或者执行此人后面的语句)。所以CPU的利用率100%。第一个人I/O结束了,就要用事件来通知线程,执行回调函数。此时必须有事件环,就有一个人排队调度机制。Node中有超过半数的C++代码,在搭建事件环


nodejs适合做:

大量的/并发的、网络,文件 I/O

例如,表单提交、考试系统,聊天室,图文直播


不适合做:

由于nodejs善于io不善于计算,复杂的业务逻辑运算



nodejs中回调是优美的实现,这句话没错,但总有些时候我们不想因为异步回调而产生一些不必要的麻烦

存在的问题:

/**
 * 需求是遍历某文件夹,只遍历一级(文件或文件夹)中的文件夹,并打印到控制台
 */
let fs = require("fs");
let http = require("http");

// 1.模拟本地服务器
let server = http.createServer(function(req, res){
    // 2.规避调由chrome浏览器收藏夹发起的访问的请求
    if(req.url == '/favicon.ico'){
        return;
    }
    
    // 3.读取一个文件夹
    fs.readdir('./album', function(err, files){
        // 4.声明一个空数组来存放所有的子文件夹
        let folderArray = [];


        // 此处的就是因为nodejs的回调'太过于无处不在'导致会出现局部变量污染的问题,
        // 分析如下: 
        // 假设files[0]='folder1',
        // 试着想一下由于是异步回调,当第一个for循环走完,获取if中的判断还没有执行到,
        // 紧接着for走到第二次循环此时files[2]='a.txt',此时if判断恰巧执行到,
        // 试问此时的folderArray.push(files[i]);就不是'folder1',而是'a.txt'
        // 于是问题就出现了!
        for(var i = 0; i < files.length; i ++){
            fs.stat('./album/' + files[i], function(err, stats){
                if(stats.isDirectory()){
                    folderArray.push(files[i]);
                }
                console.log(folderArray);
            });
        }
        console.log(folderArray);
    });
    
    res.end();

}).listen(3000, '127.0.0.1');



纠正方案

/**
 * 需求是遍历某文件夹,只遍历一级(文件或文件夹)中的文件夹,并打印到控制台
 */
let fs = require("fs");
let http = require("http");

// 1.模拟本地服务器
let server = http.createServer(function(req, res){
    // 2.规避调由chrome浏览器收藏夹发起的访问的请求
    if(req.url == '/favicon.ico'){
        return;
    }
    
    // 3.读取一个文件夹
    fs.readdir('./album', function(err, files){
        // 4.声明一个空数组来存放所有的子文件夹
        let folderArray = [];

        /**
         * 牛x的地方在这里出现,强行将同步变成异步
         *    -- 自己定义一个函数并且使之立即执行(function method(args){...})(args)
         */
        (function iterator(i){
            // 5.控制数组下标不越界
            if(i == files.length){
	        // 6.输出满足条件的文件夹
	        console.log(folderArray);
                return;
            }
            // 7.对files中的元素开始逐一遍历
            fs.stat('./album/' + files[i], function(err, stats){
                // 8.如果是文件夹则就放入上面预定义的数组内
                if(stats.isDirectory()){
                    folderArray.push(files[i]);
                }
                // 9. 此处是关键点,也正是这里才是强制同步遍历
                iterator(i + 1);
            });
        })(0);

    });
    res.end();

}).listen(3000, '127.0.0.1');




这种问题在读数据库时一定要格外注意!!!

2
0
查看评论
发表评论
* 以上用户言论只代表其个人钱柜娱乐开户,不代表CSDN网站的钱柜娱乐开户或立场

node.js在遇到“循环+异步”时的注意事项

nodejs的特征nodejs的最大特征就是一切都是基于事件的,从而导致一切都是异步的。nodejs的速度为什么快,其原理和nginx一样,他们都是通过事件回调来处理请求的,从而导致了整个处理过程中,...
  • fangjian1204
  • fangjian1204
  • 2016-01-26 09:03
  • 5620

Nodejs中“循环+异步” 好深的坑!!

这几天在搞Nodejs从数据库中获取数据进行格式转换,折腾了好几个日日夜夜,各种循环+异步操作,最后发现这玩意好恶心,怎么每次运行结果都会变,有时报错哪个值undefined有时正常,简直吐血,经历无...
  • u011249920
  • u011249920
  • 2017-01-11 08:10
  • 5346

理解nodejs的stream和pipe机制

前言前几天别人请教我关于pipe的问题,我发现我虽然用了nodejs很久,但是由于每次用的不多所以经常回避stream的使用,导致一直不熟,现在重新学习整理一下相关知识。
  • Vieri_32
  • Vieri_32
  • 2015-09-11 19:05
  • 19716

Nodejs 异步回调之异常

目前我们项目的Nodejs异常是通过express next 到 errorhandler 中间件去处理的, 原本以为此方法可以捕获到所有的异常,但事实发现并非如此。下面以一个异常举例子:req.g...
  • ForeverCjl
  • ForeverCjl
  • 2017-07-04 14:56
  • 362

nodejs 单线程,异步回调,事件

一直都说nodejs是单线程,采用事件异步回调的机制,达到非阻塞。一直很不是很理解,最近有点心得。 首先说说啥是单线程和多线程两者的区别: 单线程可以理解为任务制,在当前任务的时候要等待当前任务的...
  • caoPengFlying
  • caoPengFlying
  • 2017-10-26 09:33
  • 6445

Nodejs异步回调的优雅处理方法

前言 Nodejs最大的亮点就在于事件驱动, 非阻塞I/O 模型,这使得Nodejs具有很强的并发处理能力,非常适合编写网络应用。在Nodejs中大部分的I/O操作几乎都是异步的,也就是我们处理...
  • u012028371
  • u012028371
  • 2017-01-09 22:33
  • 268

nodejs异步回调造成的困扰

现存在如下图所示的文件目录: 我们希望通过02.js来实现能够静态加载static中的文件 这篇博客是我的上一篇博客静态资源管理续篇,在上一篇博客中,因为遇到加载json格式的文件遇到了问题,...
  • hhthwx
  • hhthwx
  • 2017-11-21 11:12
  • 54

异步回调网络请求

  • 2017-11-29 18:36
  • 1.35MB
  • 下载

dataGridView异步回调

  • 2011-01-11 17:31
  • 89KB
  • 下载

ASP.NET基于ICallbackEventHandler的轻量级异步回调

  • 2010-11-25 13:26
  • 22KB
  • 下载
    个人资料
    • 访问:9771次
    • 积分:196
    • 等级:
    • 排名:千里之外
    • 原创:9篇
    • 转载:0篇
    • 译文:0篇
    • 评论:10条
    文章分类
    文章存档
    最新评论