开课吧前端1期.阶段5:generator,模块化与babel

复习:ES6
变量let、箭头function、参数等、map、reduce、filter、forEach

Promise消除回调,Promise.all([p1,p2,p3]).then()
单独Promise并不能帮我们解决所有问题,还有2个兄弟是从Promise过度出来的,generator ,async*
generator ,async* 严格来说是属于ES7的东西
//generator怎么去用,先抛弃不要想Promise
generator 翻译:生成器
generator -- 特殊的函数
普通函数 --》   【开始执行,一路到底】 ---》飞机(没法停)
generator 函数 --》 【中间能停】 ,  踹一脚走一步  --》出租车(随时可停)


//普通函数-无法中间停
<script>
    function show(){
      alert('a');
		 //想中间停
      alert('b');
    }

    show();
</script>

//中间可以停
<script>
 function *show(){ //generator特点:星号*
      alert('a');
		  yield; //告诉在哪停
      alert('b');
  }

   let obj = show(); //执行完并不会执行函数代码,会生成generator对象
   obj.next(); //简单理解踹一下走一下,走到第一个yield停住,//alert:a
   obj.next();//alert:b
</script>   
yield可以:
	1、传参
	2、有返回值【可以阶段性传参】
	
作用:类似炒菜过程	

<script>
    function *show(){
      alert('a');
     
        yield 12;

      alert('b');

      return 5;
    }

    let obj=show();

    let res1=obj.next();      //{value: 12, done: false} //done有没有完成
    console.log(res1);

    let res2=obj.next();      //{value: 5, done: true}
    console.log(res2);
</script>

//传参
<script>
    function *show(a,b){
      alert('a');
      console.log(a,b);

      let c=yield;
      console.log(c);

      alert('b');

      return 5;
    }

    let obj=show(12, 5);

    let res1=obj.next();//undefine 第一次next没有结果【下图理解】
    let res2=obj.next(888);
</script>

 

 

用在哪里?

为什么好好函数?中间需要停一下?,例如:生活打车为什么中间要停一下【接人,忘了东西】

程序中为啥要停一下,等待某些操作结束,例如:数据交互。

function *show(){
     xxx
     xxx
     
     let data1 = yield $.ajax('a.text')
     
     xxx
     xxx
     
     let data2 = yield $.ajax('b.text')
     
     xxx
     xxx
}

比方说我有个函数,等待a请求的ajax结束,然后收集数据data1,等下下一个b的ajax请求,我们知道generator函数走到yield要暂停,next()往下执行。但是我们是否可以通过同步写法,完成异步的操作?

需要辅助工具
node小工具
安装cnpm
npm install -g cnpm --registry=https://registry.npm.taobao.org
cnpm search yield-runner-blue  //跳出网页,搜索yield-runner-blue
cnpm i yield-runner-blue  //安装 install 
//会在当前cmd路径下,有个node_modules/yield-runner-blue 文件夹 


//演示,runner封装特点:即享受到异步带来的性能优势,同时兼顾到了你写代码的习惯
<script src="runner.js" charset="utf-8"></script>
<script src="jquery.js" charset="utf-8"></script>
<script>
    
    //generator函数不能用箭头函数
    
    runner(function *(){ 
      alert('欢迎哈');

      //等下数据结束,什么时候结束什么时候往下执行
      let arr=yield $.ajax({url: 'data/1.txt', dataType: 'json'}); 

      alert('接收到了数组'+arr);

      let json=yield $.ajax({url: 'data/2.txt', dataType: 'json'});

      alert('json也读完了');

      console.log(json);
    });
 



作业1:看懂runner.js [yield-runner-blue的index.js]
作业2:搞懂传统的ajax请求和generator区别,优缺点
	演示中的generator,需要依赖一个runner.js
    既然generator那么好用,ES7官方也出一个runner【async/await】

 

async / await

既然runner.js那么好用,官方为啥不出一样
es7出了一个叫做: async / await

 <script>
     async function show(){
      alert('欢迎哈');

      let arr=await $.ajax({url: 'data/1.txt', dataType: 'json'});

      alert('接收到了数组'+arr);

      let json=await $.ajax({url: 'data/2.txt', dataType: 'json'});

      alert('json也读完了');

      console.log(json);
    }

    show(); //函数调用
    </script>


  <script>
     //省略,箭头函数
    (async ()=>{
      alert('欢迎哈');

      let arr=await $.ajax({url: 'data/1.txt', dataType: 'json'});

      alert('接收到了数组'+arr);

      let json=await $.ajax({url: 'data/2.txt', dataType: 'json'});

      alert('json也读完了');

      console.log(json);
  })();

 
  </script>

总结:

promise和generator本质

Promise本质:等待异步操作结束
generator本质:无感处理异步操作
async本质:官方runner

runner(function *(){
     xxx
     let 结果1 = yield 异步操作1
     xxx
     let 结果2 = yield 异步操作2
     xxx 
});

(async function(){  //可写 async ()=>
    xxx
    let 结果1 = await 异步操作1
    xxx
    let 结果2 = await 异步操作2
    xxx 	   
})()

模块化

模块【引入一个第三方登陆模块】 或等于 【元件】 或等于 【组件】 (一个东西)

1. 民间版的-sea.js , require.js
   CMD,和 AMD 模块的规范	
   *作业3: 找找CMD和AMD是什么,区别?
   
	
2. nodejs模块化

3. ES6模块化 【官方出来以后,大家抛弃了民间】

sea.js使用

bower i seajs  【官网打不开,下载一个】

模块是什么?就是一个可以重复使用单位

模块分为2个部分:
1.定义
2.调用

----sea.js的模块使用

sea好处: 按需引用,解决依赖
//mod1.js
//exports 导出 [对外导出a和b]
//模块是被包起来的,需要写在define内部

define(function(require, exports, module)){ //define是有参数的
    exports.a=12;
	exports.b=5;  
    exports.calc=function (){  } //函数外部出口

   //module作用:批量导出
   module.exports={
     a: 12, b: 5,
      show(a, b){
        alert(a+b);
      }
  };

  //require  用来引用其他模块

      
})

//直接定义是无法使用的,只能在内部,作用域
//let a=12;
//let b=5;
//1.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <!--
           不能这么使用,不然失去模块化的意义
          <script src="mod1.js" charset="utf-8"></script>
     -->  
      
    <script src="sea.js" charset="utf-8"></script>
    <script>
        seajs.use(['mod1.js'], function (mod1){ //use引用模块
           //回调函数 
          mod1.show(mod1.a, mod1.b);
        });
    </script>
  </head>
  <body>

  </body>
</html>



//总结:
//1.定义模块 mod1.js
define(function(require,exports,module){
     exports.a=12;
     exports.b=5;
});

//2.引用模块   1.html
seajs.use(['xxx.js','bbb.js'],function(mod1){})


//ES6的JSON的,key和value一样,可以简写
let a=12;
let b=6;
let json={a,b};

//函数可以缩写
{
    show:function(){}  //原来写法
    show(){}           //新写法
}

require概念

 

-- mod2.js
define(function (require, exports, module){
  let moda=require('./a.js');
  let modb=require('./b.js');

  exports.res=moda.num1+modb.num2;
});
-- 2.html
<script src="sea.js" charset="utf-8"></script>
    <script>
    seajs.use('mod2',function (mod){
      alert(mod.res); //
    });
</script>

 

node.js使用

seajs和require.js 本身消息了,但是这种用法还是存在的,只不是在node.js上体现

如果我是拿着html去找js,使用:use
如果在js文件里面再去找js,使用:require
在node.js里面没有use,只有require,因为都是js找js

 

//3.js
//define() ,原来是要使用define,现在不需要了 

exports.a=12;  //输出a:12

 

//2.js
exports.b=55;   //输出b:55

 

//1.js
let mod2 = require('./2');//.js可以省略,同名js使用直接使用名字:2.js = 2
let mod3 = require('./3.js');

console.log(mod2.a+mod3.b);  

 

 

 

node.js,点的使用,node_modules

 

//seajs里面
define(function(){
    let moda = require('./a');
    let modb = require('./b');
    //可以把.点给去掉,是一样的,可有可无
    let moda = require('a');
    let modb = require('b');

});


//node.js里面
let mod2 = require('2');
let mod3 = require('3.js');
//报错
//Cannot find moudle '2'
//为什么: 在reajs,require.js里面只有你定义的的模块,没有别人的模块,而node.js不一样,包含有系统模块,再带的模块,http等

let http=requier('http'); //引用系统模块
console.log(http);  

let http2=requier('./http'); //引用自定义模块, ./表示在当前文件夹下查找http.js
console.log(http2);  

//node_modules
//想引用自己的模块,但是每次都要加【./】好麻烦,可以有一个文件夹【node_modules】,这个名字不能乱动,不能改,必须叫这个,因为默认会去这里面找东西。
let mod2 = require('2');  //这时候不带./也能出来
let mod3 = require('3.js');

console.log(mod2.a+mod3.b); //正常输出:67

总结:

node的模块化
1.没有define
2.exports,require,module
3.引用自定义模块
	放到node_modules里
	前面加./

 

创建模块

--创建自己的包,发布给别人用 
--node的东西习惯前面有个nmath,用于区别系统的math

1.创建文件夹 nmath
2.创建包信息  npm init
    --pack name(nmath)
    --description: this is my math package【输入描述】
    --entry point: a.js  【入口文件,当别人引用你包时候,到底引用是谁】
    --test command:  【你做出来东西,有相应的测试,帮你来测试的命令】
    --git repository: 【托管的地址】
    --keywords: math my【便于别人搜索】
    --author: lisi 【作者是谁】
    --license: (ISC): 【许可】
    -- is this ok ? 
        
//生成package.json     
{
  "name": "nmath",
  "version": "0.0.1",
  "description": "this is my math package",
  "main": "a.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "math",
    "my"
  ],
  "author": "lisi",
  "license": "ISC"
}

//a.js 入口
module.exports={
  sum(a,b){  //加法
    return a+b;
  },
      
  divide(a,b){ //除法
    return a/b;
  }
};

    
3.把你的包放到node_modules

4.使用require('nmath') //加载
//test_nmath.js
const nmath=require('nmath'); //相当于require('a.js')
console.log(nmath.divide(12, 66));

5.执行测试
node test_nmath

//让全世界都用上你的包, 发布你的包
6.npm publish
  --错误:err! code e403,verify your email 【先验证你的邮箱,先登陆】
  --登陆:npm login 【会传到官网: www.npmjs.com】
  --再次  npm publish

 

ES6模块和Node区别  

ES6模块化:首先官方提供的,首先用官方的,一个性能好,一个统一标准
ES6出了2个新东西:import、export
原来民间版本不是叫:require,现在ES6官方叫:import

//官方语法解释怎么用
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export

 

 

//1.js
let a=12; //不输出是用不了的
let b=5;

export{a,b}

//import.html
<script>
    import mod1 from "./1.js"
    alert(mod1.a);  //Unexpected token import 目前浏览器还不是很支持ES6模块化 import
    alert(mod1.b);
</script>    

//目前浏览器不是很支持ES6模块化,有没有什么办法?
//靠工具来帮我们,ES6尽管是官方的,还是需要工具的支撑
1、ES6---目前没法浏览器用--可以用babel编译,babel可以编译普通JS代码,但是无法编译es6模块,编译模块需要WebPack

2、WabPack  

es6与node模块区别

//语法不同

Node:
输出
exports.a=12;
module.exports={x, x, x};
引入
let mod=require('./aaa.js');


ES6:
输出
export {x, x, x};
引入
import mod from "./xxx.js"  //加了mod可以直接用

  

babel

babel不能编译模块,但是能编译ES6,可以帮助我们理解工具如何用
babel官网: https://babeljs.io/

 

  

//如何使用babel

1、.安装babel-cli
  cli全称:command line interface  //命令行接口
  build: babel src -d lib  == npm run build
  npm i -g babel-cli //全局安装
  
2、在文件夹编译,创建文件夹babel_es6
//创建 1.js 文件, 大量用到es6特性
let a=12;
const b=5;

let arr=[{a, b}, {b, a}];

arr.sort((json1, json2)=>json1.a=json2.a);

alert(arr[0].a);


//1.html,在谷歌浏览器Chrome可以运行,在IE11浏览器无法运行
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <script src="js/1.js" charset="utf-8"></script>
  </head>
  <body>
  </body>
</html>

//2.由于IE无法运行,需要编译
//3.进入目录babel_es6
 npm init //建立一个package.json,就是工程文件
 //需要在scripts加一个build,目前我们暂时用不到,但是后面用到很多
   "scripts": {
    	"build": "babel js -d build"
    }
 //script用处:保存写好的命令,不用每次都打
 //假如我们在命令行输入命令: node server.js --slience --no-err --report=c:/a.txt
 //正常启动 server.js 我需要在后面带一堆的参数,每次都要写那么多参数累死了。所以可以在
 //script里面加名字,例如:serv
 	"scripts": {
    	"serv": "node server.js --slience --no-error --report=c:\\a.txt"
     }
 //运行的时候就可以:npm run 【npm run 这2个是固定的】
 // npm run serv 【效果等同于node server.js --slience --no-error --report=c:\\a.txt】


//4.运行试试
babel js -d build  //在js里面夹里面变异js文件到build文件夹
//执行后会生成build文件夹,存放处理后js文件
//报错:Error: Couldn't find preset "env" relative to directory
//需要安装安装babel-preset-env,同样是在项目的根目录下通过以下命令行安装:
//npm install -D babel-preset-env 

//5.然后运行 npm run build 或者 babel js -d build
js\1.js -> build\1.js  //成功后,1.js文件变成了,bulid/1.js

//6.运行成功后,发现js文件内容没有什么变化,除了整齐点

//7.创建 .babelrc 配置文件
{
  "presets": ["env"]  //presets预设,说白了babel需要大量选项需要配置,我听谁的,是你一个个给我,还                       //是我默认去找一个叫做env的,说明babel有很多种模式,env就是其中一种
                      //安装npm install babel-preset-env --save-dev
    				  //--save-dev 就等于  -D  ,开发环境依赖
                      //--save 是生产环境依赖 
}

//8.package.json 文件变化,增加了devDependencies
  "devDependencies": { //dev开发,devDependencies依赖: 开发模式的依赖的模块
    "babel-preset-env": "^1.7.0"   
  }

 

 

babel编译模块

文件夹结构:

/js/mod/m1.js

/js/mod/m2.js

/js/2.js

//m1.js
let a=12;
export {a};

//m2.js
let b=12;
export {b};

//2.js
import m1 from "./mod/m1.js"
alert(m1.a);


//编译模块
npm run build

//编译完后/build/2.js,内容
"use strict";

var _m = require("./mod/m1.js");

var _m2 = _interopRequireDefault(_m);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

alert(_m2.default.a);


//出现了require,我们知道require原生JS无法使用。其实babel直接编译export,import作用不明显,看不到效果,还是需要搭配其他工具。

  

总结作业

1、看yield-runner

2、看AMD和CMD的区别

3、尝试webpack编译import 和 export

  

  

  

  

posted @ 2024-01-07 16:04  兔兔福  阅读(9)  评论(0编辑  收藏  举报