异步流程工具的使用

前端的异步流程

传统的原生异步的两种解决方法: 回调函数事件

异步流程工具的使用

1.1 promise
  1. Promise 是异步编程的一种解决方案,比传统的解决方案回调函数和事件更合理和更强大。

  2. Promise 由社区最早提出和实现,ES6将其写进了语言标准,统一了语法,原生提供了Promise

  3. 所谓Promise ,简单说就是一个容器,里面保存着某个未来才会结束的事件 (通常是一个异步操作)的结果。

  4. Promise从语法上来说,它是一个对象,从它那里可以获取异步操作的消息。

  5. Promise 对象的状态不受外界影响

  6. Promise 对象的三种状态:

    • pending:进行中
    • fulfilled :已经成功
    • rejected 已经失败
  7. Promise对象的状态改变,只有两种可能:

    • 从pending变为fulfilled
    • 从pending变为rejected。
    • 这两种情况只要发生,状态就凝固了,不会再变了,这时就称为resolved(已定型)
  8. Promise.all和Promise.race的使用

    • Promise.all获得的成功结果的数组里面的数据顺序和Promise.all接收到的数组顺序是一致的
    • Promise.race数组里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态
    const p1 = new Promise( ( resolve,reject ) => {
        resolve( '任务一' )
    }).then ( data => {
        console.log( data )
    })
    
    const p3 = new Promise( ( resolve,reject ) => {
        setTimeout( () => {
            resolve( '任务三' )
        },3000)
    }).then ( data => {
        console.log( data )
    })
    
    const p2 = new Promise( ( resolve,reject ) => {
        setTimeout( () => {
        resolve( '任务二' )
        },2000)
    }).then ( data => {
        console.log( data )
    })
    
    console.log( '主线程任务' )
    
    //Promise.all( [taskOne,taskTwo,taskThree],() => { 
   // })
    //主线程任务
   //任务一
   //任务三
   //任务二
   
    Promise.race( [taskOne,taskTwo,taskThree],() => {
     })
    //主线程任务
   //任务一
   //任务三
   //任务二

1.2 es6——generator函数

  1. 在function关键字后面加一个 * 这样定义的函数就叫做generator函数
    function *fn () {}
  1. generator函数通过 yield 关键字来定义任务

  2. generator函数通过 fn().next() 来执行任务

    • value表示yield关键字后任务执行的结果
    • done表示当前定义的所有的任务是否执行完成的一个状态
  3. 理解:多任务的定义,多任务执行

    • 让自己定义的多个任务依次执行,上一个任务如果没有完成,下一个任务就不会开始
    function * fn () {
        yield '任务一'
        yield '任务二'
        return '任务'
    }
    const a = fn();
    console.log( a.next() ); // { value: '任务一',done: false }
    console.log( a.next() );//{ value: '任务二',done: false }
    console.log( a.next() );//{ value: '任务', done: true }
    console.log( '主线程任务' );// 主线程任务

1.3 es6/7——async 函数

async函数由es6提供,配合关键字 awai t使用;await 表示等待,任务一执行结束之后,才会执行任务二

    async function fn () {
        const result = await '任务一'
        console.log( result )
        console.log( '任务二' )
    }
    fn()
    // 任务一
   //任务二

1.4 node.js中的 nextTick、setImmudiate

  1. nextTick()的回调函数执行的优先级要高于setImmediate()。

  2. process.nextTick()属于idle观察者,setImmediate()属于check观察者。 在每一轮循环检查中,idle观察者先于I/O观察者,I/O观察者先于check观察者。

    • nextTick > 回调函数 > setImmediate
  3. 在具体实现上,process.nextTick()的回调函数保存在一个数组中,setImmediate()的结果则是保存在链表中。

  4. 在行为上,process.nextTick()在每轮循环中会将数组中的回调函数全部执行完。而setImmediate()在每轮循环中执行链表中的一个回调函数.

    //加入2个nextTick()的回调函数
    process.nextTick(function(){
        console.log("nextTick延迟执行A");
    });
    
    process.nextTick(function(){
        console.log("nextTick延迟执行B");
        setImmediate(function(){
            console.log("setImmediate延迟执行C");
        });
        process.nextTick(function(){
            console.log("nextTick延迟执行D");
        });
    });
    
    //加入两个setImmediate()回调函数
    setImmediate(function(){
        console.log("setImmediate延迟执行E");
        process.nextTick(function(){
            console.log("强势插入F");
        });
        setImmediate(function(){
            console.log("setImmediate延迟执行G");
        });
    });
    
    setImmediate(function(){
        console.log("setImmediate延迟执行H");
        process.nextTick(function(){
            console.log("强势插入I");
        });
        process.nextTick(function(){
            console.log("强势插入J");
        });
        setImmediate(function(){
            console.log("setImmediate延迟执行K");
        });
    });
    console.log("正常执行L");
    
    //正常执行L
    //nextTick延迟执行A
    //nextTick延迟执行B
    //nextTick延迟执行D
    //setImmediate延迟执行E
    //强势插入F
    //setImmediate延迟执行H
    //强势插入I
    //强势插入J
    //setImmediate延迟执行C
    //setImmediate延迟执行G
    //setImmediate延迟执行K
  1. 轮询: 一个事件往复执行,那么每一次执行完成,我们就认为是一个轮询
    事件轮询前,我们使用nextTick
    事件轮询后,我们使用setImmediate

1.5 第三方的 async.js 库

功能:

  1. 可以实现异步
  2. 串行series和并行parallel
    const async = require( 'async' )
    
    //series
    async.series({
        one: function ( callback ) {
            setTimeout( function () {
                callback( null, 1)
            },200)
    },
        two: function ( callback ) {
            setTimeout( function () {
                callback ( null , 2 )
            },100)
        }
    }, function ( error , results ) {
        console.log( 'series',results )
    })
    console.log( '主线程' )
    
    //parallel
    async.parallel({
        one: function ( callback ) {
            setTimeout( function () {
                callback( null, 1)
            },200)
        },
        two: function ( callback ) {
            setTimeout( function () {
                callback ( null , 2 )
            },100)
        }
    }, function ( error , results ) {
        console.log( 'parallel',results )
    })

    //主线程
    //parallel { two: 2, one: 1 }
    //series { one: 1, two: 2 }

参考资料

  1. Promise:https://blog.csdn.net/MrJavaweb/article/details/79475949

  2. Generator:https://www.cnblogs.com/imwtr/p/5913294.html

  3. Async-await:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/async_function

  4. Node.js 中的nextTick()和setimmediate():https://www.cnblogs.com/5ishare/p/5268273.html

  5. async库:https://caolan.github.io/async/

总结

异步流程的任务是放在异步队列中的,异步队列只有在主线程执行完之后采取执行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值