作者: admin

  • async/await笔记

    es7语法,主要作用让异步操作更简单,在Generator函数基础上优化得来

     

    Generator 函数

    var gen = function* () {
      var f1 = yield readFile('/etc/fstab');
      var f2 = yield readFile('/etc/shells');
    };

     

    调用:

    gen().next()
    gen().next()
    gen().next()
    ...

     

     

    async函数

    var asyncReadFile = async function (){
      var f1 = await readFile('/etc/fstab');
      var f2 = await readFile('/etc/shells');
    };

     

    调用:

    asyncReadFile()

     

    async函数就是将 Generator 函数的星号(*)替换成async,将yield替换成await,仅此而已。
    调用的方法也明显不同,Generator需要使用next()来一个个调用,而async跟普通函数调用一样

    http://es6.ruanyifeng.com/?search=await&x=5&y=7#docs/async 

     

     

     

    async/await其实是Generator函数的语法糖。异步编程可以使用async/await配合Promise对象来实现,语法易读。

    要理解async/await在js中的执行顺序,没有一点基础理论支持是很难理解的。

     

    1,async 用于申明一个 function 是异步的,所以在该function里面的程序都是异步的,但有时也需要依赖某个函数执行完成得到结果才能继 续执行,这时候可以在函数体里面使用await

    2,await 只能出现在 async 函数中

    3,await后面可以接着一个直接变量或者是一个promise对象

    4,await后面接着是promise对象,async函数体内就会阻塞要等await后面的promise函数执行完成才会继续往下走。async函数体外的代码可不 会去一直等待。

    5,如果在函数中 return 一个直接量,async 会把这个直接量通过 Promise.resolve() 封装成 Promise 对象。

    6,在没有 await 的情况下执行 async 函数,它会立即执行,返回一个 Promise 对象,并且,绝不会阻塞后面的语句。这和直接new Promise 对象效果一样。

     

    关于async更多了解,查看此案例更直接:async.html

    修改后async.html

     

     

     

     

     

     

     

  • Node.js执行Unix shell命令

    node shell

    1,创建一个shell可执行程序,名称为hello (无扩展名)
    #!/usr/bin/env node
    console.log(‘hello world’);

     

    2,赋予可执行权限
    chmod 755 hello

    3,创建package.json

     {
       "name": "hello",
         "bin": {
          "hello123": "hello"
         }
     }

     

    4,创建可执行程序的hello软链接到node.js全局模块的安装目录下,目的是在执行hello程序是可以不用指定目录了
    npm link

    5,直接在shell命令中执行
    hello123

    —————————以上是快速上手篇————————-

    执行 Unix 系统命令,模块shelljs负责调用命令行,
    ShellJS 是 Node.js 扩展,用于实现 Unix shell 命令执行,支持 Windows。

    npm install --save shelljs

     

    模块yargs负责解决处理命令参数的问题

    npm install --save yargs

     

     

     

     

     

     

  • 基于vue.js在input输入框的金钱货币格式化

    vuemoney

    直接上代码:

    var vm= new Vue({
     el: '#repeat',
     data: {
      value1:''
     }
    })
    
    
     vm.$watch('value1',function (newvalue,oldvalue) {
    
       newvalue_=(newvalue.indexOf('.00')>0)?newvalue.replace('.00' ,''):newvalue; //禁止ie8,9自动添加.00的小数点
    
       if( (isNaN(parseFloat(newvalue_.replace(/,/ig,'')))) ){ //如果当前输入的不是数字就停止执行
         this.value1='';  //防止不是数字是input出现NaN提示
         return false;
       }
    
       if( /\./i.test(newvalue_) ){ //判断处理含有.的情况下
    
          if(/\.\d\d\d$/.test(newvalue_)){
            this.value1=oldvalue; //限制只能输入2位小数点
          }else{
            this.value1=newvalue_.replace(/[^\d\.\,]/ig,'') //开始输入小数点之后,只能输入数字
          }
    
       }else{
          this.value1=((parseFloat(newvalue_.replace(/,/ig,'')).toLocaleString()).toString()).replace('.00' ,'');
       }
    
     })
    
    
    <div id="repeat">
     <input type="text" v-model="value1" placeholder="哈哈">
    </div>
    
    
    

     

     

     

     

     

     

  • setTimeout 秘密

    描述:计时器setTimeout是我们经常会用到的,它用于在指定的毫秒数后调用函数或计算表达式。

    语法:setTimeout(code, millisec, args)

    注意:如果code为字符串,相当于执行eval()方法来执行code。

    当然,这一篇文章并不仅仅告诉你怎么用setTimeout,而且理解其是如何执行的。

     

    1、setTimeout原理

    var start = new Date(); 
    var end = 0; 
    setTimeout(function() { 
     console.log(new Date() - start); 
    }, 500); 
    while (new Date() - start <= 1000) {}

    在上面的代码中,定义了一个setTimeout定时器,延时时间是500毫秒。

    你是不是觉得打印结果是: 500

    可事实却是出乎你的意料,打印结果是这样的(也许你打印出来会不一样,但肯定会大于1000毫秒):

    QQ20170118-141840@2x

    这是为毛呢?

    究其原因,这是因为 JavaScript是单线程执行的。也就是说,在任何时间点,有且只有一个线程在运行JavaScript程序,无法同一时候运行多段代码。

    再来看看浏览器下的JavaScript。

    浏览器的内核是多线程的,它们在内核控制下相互配合以保持同步,一个浏览器至少实现三个常驻线程:JavaScript引擎线程,GUI渲染线程,浏览器事件触发线程。

    • JavaScript引擎是基于事件驱动单线程执行的,JavaScript引擎一直等待着任务队列中任务的到来,然后加以处理,浏览器无论什么时候都只有一个JavaScript线程在运行JavaScript程序。
    • GUI渲染线程负责渲染浏览器界面,当界面需要重绘(Repaint)或由于某种操作引发回流(Reflow)时,该线程就会执行。但需要注意,GUI渲染线程与JavaScript引擎是互斥的,当JavaScript引擎执行时GUI线程会被挂起,GUI更新会被保存在一个队列中等到JavaScript引擎空闲时立即被执行。
    • 事件触发线程,当一个事件被触发时,该线程会把事件添加到待处理队列的队尾,等待JavaScript引擎的处理。这些事件可来自JavaScript引擎当前执行的代码块如setTimeout、也可来自浏览器内核的其他线程如鼠标点击、Ajax异步请求等,但由于JavaScript的单线程关系,所有这些事件都得排队等待JavaScript引擎处理(当线程中没有执行任何同步代码的前提下才会执行异步代码)。

     

    到这里,我们再来回顾一下最初的例子:

    var start = new Date(); 
     
    var end = 0; 
     
    setTimeout(function() { 
     
     console.log(new Date() - start); 
     
    }, 500); 
     
    while (new Date() - start <= 1000) {}

    虽然setTimeout的延时时间是500毫秒,可是由于while循环的存在,只有当间隔时间大于1000毫秒时,才会跳出while循环,也就是说,在1000毫秒之前,while循环都在占据着JavaScript线程。也就是说,只有等待跳出while后,线程才会空闲下来,才会去执行之前定义的setTimeout。

    最后 ,我们可以总结出,setTimeout只能保证在指定的时间后将任务(需要执行的函数)插入任务队列中等候,但是不保证这个任务在什么时候执行。一旦执行javascript的线程空闲出来,自行从队列中取出任务然后执行它。

    因为javascript线程并没有因为什么耗时操作而阻塞,所以可以很快地取出排队队列中的任务然后执行它,也是这种队列机制,给我们制造一个异步执行的假象。

     

    2、setTimeout的好搭档“0”

    也许你见过下面这一段代码:

    setTimeout(function(){
     
     // statement
     
    }, 0);

    上面的代码表示立即执行。

    本意是立刻执行调用函数,但事实上,上面的代码并不是立即执行的,这是因为setTimeout有一个最小执行时间,当指定的时间小于该时间时,浏览器会用最小允许的时间作为setTimeout的时间间隔,也就是说即使我们把setTimeout的延迟时间设置为0,被调用的程序也没有马上启动。

    不同的浏览器实际情况不同,IE8和更早的IE的时间精确度是15.6ms。不过,随着HTML5的出现,在高级版本的浏览器(Chrome、ie9+等),定义的最小时间间隔是不得低于4毫秒,如果低于这个值,就会自动增加,并且在2010年及之后发布的浏览器中采取一致。

    所以说,当我们写为 setTimeout(fn,0) 的时候,实际是实现插队操作,要求浏览器“尽可能快”的进行回调,但是实际能多快就完全取决于浏览器了。

    那setTimeout(fn, 0)有什么用处呢?其实用处就在于我们可以改变任务的执行顺序!因为浏览器会在执行完当前任务队列中的任务,再执行setTimeout队列中积累的的任务。

    通过设置任务在延迟到0s后执行,就能改变任务执行的先后顺序,延迟该任务发生,使之异步执行。

    来看一个网上很流行的例子:

    document.querySelector('#one input').onkeydown = function() { 
     document.querySelector('#one span').innerHTML = this.value; 
    }; 
     
    document.querySelector('#second input').onkeydown = function() { 
     setTimeout(function() { 
     document.querySelector('#second span').innerHTML = document.querySelector('#second input').value; }, 0);
    };

    当你往两个表单输入内容时,你会发现未使用setTimeout函数的只会获取到输入前的内容,而使用setTimeout函数的则会获取到输入的内容。

    这是为什么呢?

    因为当按下按键的时候,JavaScript 引擎需要执行 keydown 的事件处理程序,然后更新文本框的 value 值,这两个任务也需要按顺序来,事件处理程序执行时,更新 value值(是在keypress后)的任务则进入队列等待,所以我们在 keydown 的事件处理程序里是无法得到更新后的value的,而利用 setTimeout(fn, 0),我们把取 value 的操作放入队列,放在更新 value 值以后,这样便可获取出文本框的值。

    未使用setTimeout函数,执行顺序是:onkeydown => onkeypress => onkeyup

    使用setTimeout函数,执行顺序是:onkeydown => onkeypress => function => onkeyup

    虽然我们可以使用keyup来替代keydown,不过有一些问题,那就是长按时,keyup并不会触发。

    长按时,keydown、keypress、keyup的调用顺序:

    keydown
     
    keypress
     
    keydown
     
    keypress
     
    ...
     
    keyup

    也就是说keyup只会触发一次,所以你无法用keyup来实时获取值。

    我们还可以用setImmediate()来替代setTimeout(fn,0):

    if (!window.setImmediate) { 
     window.setImmediate = function(func, args){ 
     return window.setTimeout(func, 0, args); 
     }; 
     
     window.clearImmediate = window.clearTimeout; 
    }

    setImmediate()方法用来把一些需要长时间运行的操作放在一个回调函数里,在浏览器完成后面的其他语句后,就立刻执行这个回调函数,必选的第一个参数func,表示将要执行的回调函数,它并不需要时间参数。

    注意:目前只有IE10支持此方法,当然,在Nodejs中也可以调用此方法。

     

    3、setTimeout的一些秘密

    3.1 setTimeout中回调函数的this

    由于setTimeout() 方法是浏览器 window 对象提供的,因此第一个参数函数中的this其实是指向window对象,这跟变量的作用域有关。

    看个例子:

    var a = 1; 
    var obj = { 
     a: 2, 
     test: function() { 
     setTimeout(function(){ 
     console.log(this.a); 
     }, 0); 
     } 
    }; 
    obj.test(); // 1

    不过我们可以通过使用bind()方法来改变setTimeout回调函数里的this

    var a = 1; 
    var obj = { 
     a: 2, 
     test: function() { 
     setTimeout(function(){ 
     console.log(this.a); 
     }.bind(this), 0); 
     } 
    }; 
    obj.test(); // 2

    3.2 setTimeout不止两个参数

    我们都知道,setTimeout的第一个参数是要执行的回调函数,第二个参数是延迟时间(如果省略,会由浏览器自动设置。在IE,FireFox中,第一次配可能给个很大的数字,100ms上下,往后会缩小到最小时间间隔,Safari,chrome,opera则多为10ms上下。)

    其实,setTimeout可以传入第三个参数、第四个参数….,它们表示神马呢?其实是用来表示第一个参数(回调函数)传入的参数。

    setTimeout(function(a, b){ 
     console.log(a); // 3
     console.log(b); // 4
    },0, 3, 4);

     

    http://mp.weixin.qq.com/s/iyMgSw9DFTWkOmxzEiYRZQ 

     

     

  • ubuntu安装node.js版本控制器nvm

    1,

    sudo apt-get install git

     

    2,

    git clone https://github.com/creationix/nvm.git ~/.nvm && cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`

     

    3,

    cd //切换到root默认管理员目录
    vim .bashrc   //编辑此文件
    
    在文件.bashrc最底部添加代码
    source ~/.nvm/nvm.sh

     

    4, 保存后执行以下代码立马生效

    source .bashrc

     

    5, 直接输入nvm测试看看是否安装成功

     

    mac安装nvm参考: https://sdeno.com/?p=5555 一些nvm用法: https://sdeno.com/?p=5552 https://sdeno.com/?p=5557