• js异步编程


    js语言的执行环境是"单线程":一次只能完成一件任务,如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以此类推。

    这种模式的好处是实现起来比较简单,执行环境相对单纯;坏处是只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。常见的浏览器无响应(假死),往往就是因为某一段Javascript代码长时间运行(比如死循环),导致整个页面卡在这个地方,其他任务无法执行。

    为了解决这个问题,Javascript语言将任务的执行模式分成两种:同步(Synchronous)和异步(Asynchronous)。

    "同步模式"就是上一段的模式,后一个任务等待前一个任务结束,然后再执行,程序的执行顺序与任务的排列顺序是一致的、同步的;"异步模式"则完全不同,每一个任务有一个或多个回调函数(callback),前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前一个任务结束就执行,所以程序的执行顺序与任务的排列顺序是不一致的、异步的。

    一、回调函数

    function f2(){
        console.log("f2") // f2的代码
    }
    function f1(callback){
        console.log("f1"); // f1的代码
        setTimeout(function(){
            callback();
        }, 1000);
    }
    
    > f1(f2)
    f1
    f2

    同步变异步,f1不会阻塞f2。简单; 高度耦合,每个任务只能指定一个回调函数,无法return/try/catch/throw。

    二、事件监听

    function f2(){
        console.log("f2") // f2的代码
    }
    f1.on('done', f2); // 事件绑定 function f1(callback){ console.log("f1"); // f1的代码 setTimeout(function(){ f1.trigger('done'); }, 1000); } > f1(f2) f1 f2

    事件驱动,可绑定多个,去耦合。

    三、发布订阅

    function f2(){
        console.log("f2") // f2的代码
    }
    jQuery.subscribe('done', f2); // 订阅信号 function f1(callback){ console.log("f1"); // f1的代码 setTimeout(function(){ jQuery.publish('done'); // 发布信号 }, 1000); } > f1(f2) f1 f2

    类似事件监听,优于上者。

    === es6 ===

    四、Promise

    Promises对象是CommonJS工作组提出的一种规范

    Promise是一个构造函数,方法有:all、reject、resolve、then、catch

    resolve:成功

    reject:失败

    (复制到控制台查看运行结果)

    function runAsync1(){
        var p = new Promise(function(resolve, reject){
            // 做一些异步操作
            setTimeout(function(){
                console.log('异步任务1执行完成');
                resolve('随便什么数据1');
            }, 1000);
        });
        return p;            
    }
    function runAsync2(){
        var p = new Promise(function(resolve, reject){
            // 做一些异步操作
            setTimeout(function(){
                console.log('异步任务2执行完成');
                resolve('随便什么数据2');
            }, 2000);
        });
        return p;            
    }
    function runAsync3(){
        var p = new Promise(function(resolve, reject){
            // 做一些异步操作
            setTimeout(function(){
                console.log('异步任务3执行完成');
                resolve('随便什么数据3');
            }, 2000);
        });
        return p;            
    }
    
    runAsync1()
    .then(function(data){
        console.log(data);
        return runAsync2();
    })
    .then(function(data){
        console.log(data);
        return '直接返回数据';  // 这里直接返回数据
    })
    .then(function(data){
        console.log(data);
    });

    all:并行执行,谁跑得慢,以谁为准进行回掉

    Promise
    .all([runAsync1(), runAsync2(), runAsync3()]) // 并行
    .then(function(results){
        console.log(results);
    });

    race:并行执行,谁跑得快,以谁为准进行回掉

    Promise
    .race([runAsync1(), runAsync2(), runAsync3()])
    .then(function(results){
        console.log(results);
    });
    function getNumber(){
        var p = new Promise(function(resolve, reject){
            // 做一些异步操作
            setTimeout(function(){
                var num = Math.ceil(Math.random()*10); // 生成1-10的随机数
                if(num <= 5){
                    resolve(num); // 成功,获取数字
                }
                else{
                    reject('数字太大了'); //失败,传递参数
                }
            }, 2000);
        });
        return p;            
    }
    
    getNumber()
    .then(
        function(data){ // 成功
            console.log('resolved');
            console.log(data);
        }, 
        function(reason, data){ // 失败
            console.log('rejected');
            console.log(reason);
        }
    );
    // 这个和上面功能一样,但是上面有异常不会卡死
    getNumber()
    .then(function(data){
        console.log('resolved');
        console.log(data);
    })
    .catch(function(reason){
        console.log('rejected');
        console.log(reason);
    });

    五、generator

    === es7 ===

    六、async/await

    async-awaitpromisegenerator的语法糖

    参考资料

    https://www.cnblogs.com/whybxy/p/7645578.html

    https://www.cnblogs.com/chenshufang/p/9927536.html

    https://segmentfault.com/a/1190000011526612?utm_source=tag-newest

    http://www.ruanyifeng.com/blog/2012/12/asynchronous%EF%BC%BFjavascript.html?bsh_bid=1736591883

    未完待续。。。

  • 相关阅读:
    10000个线程更新同一行数据
    CountDownLatchTest
    创建 oracle dblin
    extjs日期控件使用
    JAVA Date超强工具类,可直接取代util.Date使用
    JSP&Servlet学习手册
    JAVA 文本 TXT 操作工具类
    Leetcode 526.优美的排列
    Leetcode 525.连续数组
    Leetcode 523.连续的子数组和
  • 原文地址:https://www.cnblogs.com/fogmisty/p/10382284.html
Copyright © 2020-2023  润新知