关于javascript:特皮技术团队一年经验菜鸟前端眼中的异步编程

7次阅读

共计 4486 个字符,预计需要花费 12 分钟才能阅读完成。

前端开发必不可少,什么是异步编程

  • 因为 javascript 语言是一门“单线程”的语言,所以,javascript 就像一条流水线,仅仅是一条流水线而已,要么加工,要么包装,不能同时进行多个工作和流程。
  • 而作为前端开发,在面试与工作中置信大家肯定被问过或常常须要用到异步编程,那么什么是异步编程呢?

首先咱们先辨别一下什么是同步编程,什么是异步编程。

  • 同步编程:咱们都晓得代码的执行程序是自上而下执行的,那么同步就是须要每一个工作都实现当前再去执行下一个工作,执行程序与排列程序是统一的。害处,只有有一个工作耗时很长,前面工作都必须排队等着,常见的浏览器无响应,死循环。
  • 异步编程:每一个工作有一个或多个回调函数,前一个工作执行完后,不是执行下一个工作,而是执行回调函数,后一个工作是不等前一个工作完结就执行的,所以程序的执行程序与工作的排列程序是不统一的。
  • 简略的说咱们能够将异步编程了解为在约定的工夫内实现的操作。
  • 举个简略的例子:

    • 假如你设置了一个第二天 7:00 的闹钟,那么咱们设置完,是始终在期待闹钟的揭示,再去做下一件事,还是去做别的事件,置信大家都不会傻傻的在那等,在编程里这就异步编程。

异步编程怎么判断:是否阻塞 ? 同步阻塞,异步不阻塞。

  • 那么常见的异步编程有什么呢?
  • setTimeout
  • Ajax
  • Promise
  • async 函数
  • 接下来咱们通过代码看看异步编程是如何执行的

    定时器 (setTimeOut)

  • 在规定的工夫内实现操作:点击按钮,会打印“我先执行”接着打印“执行定时器”。能够看到尽管工夫设置为 0,然而定时器里的工作并不是先被执行
<body>
    <button> 点击触发定时器 </button>
    <script>
        let btn = document.querySelector('button');
        btn.onclick = function () {setTimeout(function () {alert('执行定时器');
            }, 0)

        }
        console.log('我先执行');
    </script>
</body>

Ajax (异步 JavaScript 和 XML)

  • 首先介绍咱们先一下 Ajax。
AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)
  • Ajax 是一种无需从新加载整个页面的状况下,可能更新局部网页的技术。
  • 接着咱们通过一个简略的例子来看看 ajax 的弱小 (为了不便调用接口咱们间接应用网上链接 https://cnodejs.org/api),为了观看成果显著一些会应用点击事件让大家看看触发后果
  • Ajax 古代浏览器均反对 XMLHTTPRequest 对象,然而 IE5、IE6 须要兼容,上面就不做兼容解决了
<body>
    <button onclick="loadXML()"> 点击获取后果 </button>
    <div></div>
    <script>

        function loadXML() {let xmlhttp = new XMLHttpRequest();
            xmlhttp.onreadystatechange = function () {if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {console.log(xmlhttp)
                    document.querySelector('div').innerHTML = JSON.parse(xmlhttp.responseText).data[0].content;
                }
            }
            xmlhttp.open('GET', 'https://cnodejs.org/api/v1/topics', true)
            xmlhttp.send()
            console.log('我先执行了')
        }
    </script>

</body>
  • 能够看失去后果仍然是先打印了前面的“我先执行了”

Promise 对象

  • 什么是 promise 对象:
  • 从英文翻译来讲就是”承诺“,既然是承诺必定就须要去实现嘛,所以还是对应了下面说的,异步编程能够了解为在约定的工夫内实现的操作。
  • promise 有三种状态:pendding,fulfilled,rejected
  • pendding:初始状态,不胜利,不失败,
  • fulfilled:操作胜利
  • rejected:操作失败
  • 当 promise 状态产生扭转,就会触发 then() 里的响应函数解决后续步骤;当 promise 状态一经扭转,不会再变。
  • promise 的应用
setTimeout(() => console.log(1), 0); // 异步
const p = new Promise((resolve, reject) => {console.log(2);                 // 同步
    setTimeout(() => {console.log(4)               // 异步优先级低于 promise
    }, 0)
    resolve(3);
    console.log(5);                 // 同步
})
console.log(6)                      // 同步
p.then(value => {console.log(value);             // 异步
})

console.log(7)                      // 同步 
  • 下面这一段代码其实在面试中很常见
  • 执行后果是 2 5 6 7 3 1 4

  • 再讲后果之前咱们应该理解一下 es6 的新增的工作队列 是在事件循环之上的(onclick, setTimeout,Ajax)
  • onclick 是浏览器内核的 DOM Binding 模块来解决的,当事件触发的时候,回调函数会立刻增加到工作队列中。
  • setTimeout 是浏览器内核的 timer 模块进行的延时解决,当工夫达到后才会回调增加到工作队列中。
  • Ajax 是浏览器内核 network 模块在网络申请实现之后,将回调增加到工作队列中。
  • 代码也写了,后果也看了,然而咱们为什么要用 promise 呢?
  • 常见的答复都是解决回调天堂,其实 promise 也是用于解决异步编程的,
  • 在 promise 未呈现前,咱们的异步编程都是通过纯回调解决的
  • 举个例子
// 纯回调
function createdAsync(value,success,catch){if (value){success()
    }else{catch()
    }
}
const success = function (){console.log('胜利')
}
const catch = catch(){console.log('失败')
}

createdAsync(value,success,catch)


// promise 
const promise = createdAsync(value);
setTimeout(()=>{promise.then(success,catch);
},1000);
  • 能够看得出 纯回调的模式是先指定回调函数,在咱们想要启动异步工作前就必须指定好胜利、失败的回调函数,而且咱们不能在它实现后在指定回调函数,等他执行结束曾经获取不到数据了;
  • 而 promise 是通过执行一个函数,这个函数返回一个 promise 对象,异步操作是在这个 Promise 对象外部进行的,也就是 Promise 构造函数执行时立刻调用 executor 函数,此时异步工作开始了,然而并不需要指定胜利、失败的回调函数。
  • 能够再在来看看后面的代码(咱们将代码写的简短一些)
const p = new Promise((resolve, reject) => {console.log("executor 执行器函数"); //  executor 执行器函数
    // 异步工作
    resolve("异步")
})
p.then(value => {console.log(value);
})
console.log("new Promise 之后") 
  • 打印后果是:”executor 执行器函数“、”new Promise 之后“、“异步”

  • 所以 promsie 其实不只是解决回调天堂问题,而说到了回调天堂,其实 async 函数显得更加优化。

Async 函数

  • 什么是 async 函数
  • ES2017 规范引入了 async 函数,使得异步操作变得更加不便。
  • async 函数是什么?一句话,它就是 Generator 函数的语法糖。
  • 然而我更加偏向于 async 函数是 Promise 语法糖。咱们通过上面的例子看看。
 // 以往定义 promise 的时候
  new Promise((resolve,reject)=>{console.log('开始');
    resolve('异步');
  }).then(value => {console.log(value)})
// async 函数
  async function fn(){}
  console.log(fn())  // Promise{<fulfilled>:undefined}
  • 能够看得出 async 的返回值就是一个 Promise 对象 并且默认返回一个执行后果为胜利的 Promise 对象,也就是 new Promise() 的语法糖
  • 接着咱们看看 async 下的 await
// promise
const promise = new Promise((resolve, reject) => {resolve('异步');
})

promise.then(value => {console.log(value)
})

// async
async function fn(callback) {
    const val = await callback;
    console.log(val)
}

fn(promise)
}
  • 能够看得出 await 就是 then 的语法糖
  • 接着咱们看看这个语法糖为咱们解决了什么问题
// promise
new Promise((resolve, reject) => {resolve(1);
}).then(value => {return new Promise((resolve, reject) => {setTimeout(() => {resolve(value + 1)
        })
    });
}).then(value => {return new Promise((resolve, reject) => {setTimeout(() => {resolve(value + 1)
        })
    });
}).then(value => {console.log(value + 1)
})
console.log('我先')

// ascyn 

async function fn() {const one = await new Promise((resolve, reject) => {resolve(1)
    })
    const two = await new Promise((resolve, reject) => {resolve(one + 1)
    })
    console.log(two);
    console.log('我先')
}

fn()

  • 能够看得出 promise 的执行会 先打印出“我先”,而 asyn 函数 会将异步执行结束再进行上面的操作,所以 async 函数不仅实现了异步编程,并且在代码的上来说执行程序与排列程序是统一的。
  • 文中说的内容偏入门级别,也是联合本人所学以及了解。
  • 最初想说的是随着前端开发的一直倒退,前端开发人员把握的技术曾经不再是之前的 html+css 了(俗称的切图仔),并且前端开发人员须要把握的技术不亚于后端了,甚至须要把握一些后端常识

最初

  • 欢送关注咱们的微信公众号:【 前端巅峰
  • 继续输入原创文章
正文完
 0