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

标签: nodejs js
723人阅读 评论(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');




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

查看评论

微信支付回调node.js版数据解析问题

问题微信支付成功后回调通过POS方式返回xml格式的数据,如果回调方法中没有获取到任何xml的值,则需要安装组件body-parser-xml。安装npm install body-parser-xm...
  • linzengfa
  • linzengfa
  • 2017年05月31日 21:47
  • 1013

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

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

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

nodejs借助于node运行环境而实现的一个比较灵巧的前后一体化的开发环境,随比不了php,python,但是在快速开发维护的时间成本上,node一骑绝尘。node自身由衷的想法,花最小的硬件成本,...
  • qq_32259579
  • qq_32259579
  • 2017年06月22日 16:08
  • 723

【node】nodejs环境下多个函数异步回调统一异步回调执行结果写法

nodejs异步回调,多个回调函数的返回结果统一回调的解决方法
  • cChenLiang
  • cChenLiang
  • 2017年09月18日 08:00
  • 564

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

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

Nodejs 异步回调之异常

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

node 回调函数

Node.js 回调函数 Node.js 异步编程的直接体现就是回调。 nodeJs编辑器中运行代码:   错误代码:  var fs = require('fs');  fs....
  • zjl199303
  • zjl199303
  • 2017年04月11日 09:24
  • 190

Node.js 回调函数来解决SQL语句与返回值的异步问题

作为一个刚刚接触Node的菜鸟,面对Node的异步问题着实是头大。最近做一个前端的分页问题,原代码是顺序执行两条sql语句然后返回: client.query( //第一个sql ...
  • lhf2112
  • lhf2112
  • 2016年10月18日 13:17
  • 384

Async.js解决Node.js操作MySQL的回调大坑

由于JavaScript语言异步特性,在使用Node.js执行很多操作时都会使用到回调函数,其中就包括访问数据库。如果代码中的业务逻辑稍微复杂一点,回调一层层嵌套,那么代码很容易进入Callback ...
  • xiao__gui
  • xiao__gui
  • 2015年12月22日 12:39
  • 7290

【NodeJS】深入理解Node.js基于事件驱动的回调

回调和异步调用的关系   首先明确一点,回调并非是异步调用,回调是一种解决异步函数执行结果的处理方法。在异步调用,如果我们希望将执行的结果返回并且处理时,可以通过回调的方法解决。为了能够更好的区分回...
  • u013451157
  • u013451157
  • 2017年12月08日 21:20
  • 203
    个人资料
    持之以恒
    等级:
    访问量: 3万+
    积分: 314
    排名: 24万+
    文章分类
    文章存档
    最新评论