关于异步操作

作者: Gaarahan | 来源:发表于2018-05-19 20:20 被阅读13次

    刚开始接触NodeJs便多次听到它是 单线程异步非阻塞IO模型 ,虽然看过好多例子,然而还是不怎么理解,借着一个BUG整理下思路。


    问题

    • 尝试给一个本地的项目做一个简单的服务器时,用了如下的语句
      实际上用不着这么麻烦,这是我自己想到的处理方法
    var backHeader = {
      'html' : {
        'content-type' : 'text/html',
        'charset':'utf8'
      },
      'css' : {
        'content-type' : 'text/css',
        'charset':'utf8'
      },
      'pic' : {
        'content-type' : 'image/jpeg',
        'charset':'utf8'
      },
      'js' : {
        'content-type' : 'application/x-javascript',
        'charset':'utf8'
      }
    }
    
        ......
    //对应不同的请求后缀名,给予不同的响应报文头
        var staticHead = "";
    
        if(url.endsWith('.jpg') || url.endsWith('.jpeg'))
          staticHead = backHeader['pic'];
        else if( url.endsWith('.css') ){
          staticHead = backHeader['css'];
        }
        else if(url.endsWith('.js')){
          staticHead = backHeader['js'];
        }
        else if(url.endsWith('.html')){
          staticHead = backHeader['html'];
        }
    //读取请求的文件,并写入对应的报文头
        fs.readFile(file,function(err,data){
          if(err){
            ......
          }
          else{
            console.log(staticHead); //调试时加入的代码
            res.writeHeader(200,staticHead);
            res.write(data);
            res.end();
          }
        });
    
    
    • 但实际查看时,却发现有某些css文件的报文头出错:
      出错的报文头

    原因

    • 尝试在控制台输出了每一次的响应报文头,发现输出是这样的:


    分析这段代码的工作方式:

    • 分析传入的URL,并将对应的响应报文头存储到变量staticHead中
    • 读取URL请求的文件
    • 文件读取完毕后输出对应的响应报文头(调试代码)
    • 将读出来的文件内容写入到响应报文体中
    • 将响应报文发给浏览器来解析
    虽然每个文件的响应报文头是没问题的,但存储响应报文头的变量staticHead只有一个, 这就是问题的所在:
    • 当接收到 /css/menu.css的请求时,分析了URL并得出了正确的结果存储在staticHead 中
    • 开始读取menu.css文件
    • 接收到请求 /js/menu_js.js,开始分析URL,将结果存储在staticHead中,此时menu.css文件还没有读取出来,但它的响应报文头已经被覆盖为了js文件的响应报文头
    • menu.css 文件读取成功,写入staticHead到响应报文,写入读取的数据到响应报文
    • 将响应报文发送给浏览器
    • 浏览器接收到menu.css文件的内容,并根据响应报文头将它解析为js文件

    解决

    • 将分析URL的判断部分放到 fs.readFile(file,callback) 的回调函数部分中去
    • 利用NodeJs事件驱动的特性,只有当某个文件读取完成后,才会分析该文件的文件类型,写入到响应报文中发送给浏览器端,这个过程中,不会有其他对staticHead的操作,解决了问题

    相关文章

      网友评论

        本文标题:关于异步操作

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