JS异步方案

JS异步方案

  • 单线程和event-loop
  • callback
  • jquery的deferred
  • promise
  • async-await
  • 异步解决方案比较

单线程和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

你可能感兴趣的:(JS异步方案)