JS異步方案
單線(xiàn)程和event-loop
單線(xiàn)程:JS引擎線(xiàn)程只有一個(gè)僵驰,避免多線(xiàn)程DOM渲染沖突(GUI渲染線(xiàn)程互斥也是同理)
異步:解決JS單線(xiàn)程只能同時(shí)做一件事的問(wèn)題疯坤,
event-loop:主線(xiàn)程從任務(wù)隊(duì)列中讀取事件,這個(gè)過(guò)程是循環(huán)不斷的乘碑,實(shí)現(xiàn)異步的具體解決方案
callback
-
代碼演示:
$.ajax({ url: 'xxx', success: function(res => { }) })
jquery的deferred
概念:jquery1.5版本之后ajax的實(shí)現(xiàn)就用的deferred蛮粮,慢慢演變成promise
-
ajax的變化, 鏈?zhǔn)讲僮鳎瑢?duì)拓展開(kāi)放,對(duì)修改封閉
// 1.5前 var ajax = $.ajax({ url: 'xxx', success: function(res => {}), error: function(err => {}) }) console.log(ajax) // xhr對(duì)象 // 1.5后 var ajax = $.ajax('xxx'); // ajax.reject() 可以直接篡改結(jié)果 ajax.then(function() { // 完成 }, function() { // 失敗 }) .then(function() { // 完成2 }) console.log(ajax) // 返回deferred對(duì)象
-
其他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對(duì)象 return dtd.Promise() } return wait(dtd) } // 使用 var w = waitHandle() // w接受的是promise對(duì)象 // w.reject() 直接會(huì)報(bào)錯(cuò) $.when(w) .then(res => { // 完成1 return res }, (err) => { // 錯(cuò)誤1 }) .then(res => { // 完成2 return res })
-
總結(jié)
deferred對(duì)象:結(jié)果可以直接被篡改(resolve, reject藕溅, done匕得,then,fail)
promise對(duì)象:不可被篡改(resolve巾表, reject汁掠,then)
promise
-
代碼演示
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 => { // 統(tǒng)一捕獲異常,代碼報(bào)錯(cuò)集币,reject返回錯(cuò)誤都能捕獲 })
-
Promise.all
// 異步任務(wù)全部執(zhí)行完考阱,才能then const result1 = loadImg('xxxx'); const result2 = loadImg('yyyy'); Promise.all([result1, result2]).then(datas => { // datas是數(shù)組 console.log(datas[0]) })
-
Promise.race
// 只要有一個(gè)成功,就執(zhí)行then // result1, result2都是peomise對(duì)象 Promise.race([result1, result2]).then(data => { // 最先完成promise的返回值 console.log(data) })
-
Promise標(biāo)準(zhǔn)(ES6)
- 三種狀態(tài):pending惠猿,fulfilled羔砾,rejected
- 狀態(tài)不可逆:pending -> fulfilled(成功),pending-> rejected(失斉佳)
async-await
-
async/await標(biāo)準(zhǔn)(ES7姜凄,需要babel-polyfill)
- await必須包裹在 async 函數(shù)里面
- await 后面可以追加promise對(duì)象, 獲取resolve的值
- await 執(zhí)行返回的也是一個(gè)promise對(duì)象
- try-catch可以捕獲 promise 中reject的值
-
代碼演示
import 'babel-polyfill'; // ES7轉(zhuǎn)ES5 const load = async function () { try { // 異步變成同步寫(xiě)法,依次往下 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