JS异步方案

JS异步方案

单线程和event-loop

  1. 单线程:JS引擎线程只有一个,避免多线程DOM渲染冲突(GUI渲染线程互斥也是同理)

  2. 异步:解决JS单线程只能同时做一件事的问题,

  3. event-loop:主线程从任务队列中读取事件,这个过程是循环不断的,实现异步的具体解决方案

callback

  1. 代码演示:

    $.ajax({
        url: 'xxx',
        success: function(res => {
        
        })
    })
    

jquery的deferred

  1. 概念:jquery1.5版本之后ajax的实现就用的deferred,慢慢演变成promise

  2. ajax的变化, 链式操作,对拓展开放,对修改封闭

    // 1.5前
    var ajax = $.ajax({
        url: 'xxx',
        success: function(res => {}),
        error: function(err => {})
    })
    console.log(ajax)  // xhr对象
    
    // 1.5后
    var ajax = $.ajax('xxx');
    
    // ajax.reject() 可以直接篡改结果
    
    ajax.then(function() {
        // 完成  
    }, function() {
        // 失败
    })
    .then(function() {
        // 完成2
    })
    console.log(ajax)  // 返回deferred对象
    
    
  3. 其他Deferred的promise

        function waitHandle() {
            var dtd = $.Deferred()
            var wait = function(dtd) {
                var task = function() {
                    // success
                    dtd.resolve()
                    //error
                    // dtd.reject()
                }
                // 异步操作
                setTimeout(task, 2000)
                // 返回Promise,而不是deferred对象
                return dtd.Promise()
            }
            return wait(dtd)
        }
        
        // 使用
        var w = waitHandle() // w接受的是promise对象
        
        // w.reject() 直接会报错
        $.when(w)
        .then(res => {
           // 完成1
           return res
        }, (err) => {
            // 错误1
        })
        .then(res => {
            // 完成2
            return res
        })
    
  4. 总结

    1. deferred对象:结果可以直接被篡改(resolve, reject, done,then,fail)

    2. promise对象:不可被篡改(resolve, reject,then)

promise

  1. 代码演示

        const loadImg = (src) => {
          return new Promise((resolve, reject) => {
            const img = document.createElement('img');
            img.onload = () => {
              resolve(img);
            }
            img.onerror = () => {
              reject('加载失败');
            }
            img.src = src;
          })
        }
        // 异常捕获
        loadImg('xxxx').then(res => {
            // 成功1
        })
        .then(res => {
            // 成功2
        })
        .catch(err => {
            // 统一捕获异常,代码报错,reject返回错误都能捕获
        })
    
  2. Promise.all

        // 异步任务全部执行完,才能then
        const result1 = loadImg('xxxx');
        const result2 = loadImg('yyyy');
        Promise.all([result1, result2]).then(datas => {
            // datas是数组
            console.log(datas[0])
        })
    
  3. Promise.race

        // 只要有一个成功,就执行then
        // result1, result2都是peomise对象
        Promise.race([result1, result2]).then(data => {
            // 最先完成promise的返回值
            console.log(data)
        })
    
  4. Promise标准(ES6)

    • 三种状态:pending,fulfilled,rejected
    • 状态不可逆:pending -> fulfilled(成功),pending-> rejected(失败)

async-await

  1. async/await标准(ES7,需要babel-polyfill)

    • await必须包裹在 async 函数里面
    • await 后面可以追加promise对象, 获取resolve的值
    • await 执行返回的也是一个promise对象
    • try-catch可以捕获 promise 中reject的值
  2. 代码演示

        import 'babel-polyfill'; // ES7转ES5
    
        const load = async function () {
            try {
                // 异步变成同步写法,依次往下
                const result1 = await loadImg('xxx')
                console.log(result1)
                const result2 = await loadImg('yyy')
                console.log(result2)
            } catch (error) {
                console.log(error)
            }
        }
        load()
    

异步解决方案比较

  • callback

  • jquery的deferred

  • generator

  • Promise

  • async/await

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • JS中的单线程指的是在同一个时间内只能做一件事情。 好处:避免DOM渲染的冲突。浏览器根据HTML文件初始化需要渲...
    当垆小筑阅读 3,173评论 0 0
  • 原文连接:https://blog.csdn.net/sinat_17775997/article/details...
    小豆soybean阅读 9,737评论 0 7
  • 为什么会出现异步 js是一门为浏览器而诞生的语言,发展到现在,js已经不仅仅只在浏览器上运行了,服务端也可以运行j...
    lzksdxh阅读 10,000评论 0 2
  • # Ajax标签(空格分隔): 笔记整理---[TOC]### 从输入网址开始:- 在学习ajax之前,你应该先了...
    V8阅读 2,383评论 1 0
  • 弄懂js异步 讲异步之前,我们必须掌握一个基础知识-event-loop。 我们知道JavaScript的一大特点...
    DCbryant阅读 7,734评论 0 5

友情链接更多精彩内容