国产成人精品18p,天天干成人网,无码专区狠狠躁天天躁,美女脱精光隐私扒开免费观看

JavaScript中怎么處理異步

發(fā)布時(shí)間:2021-07-04 20:13 來(lái)源:億速云 閱讀:0 作者:Leah 欄目: 開(kāi)發(fā)技術(shù)

JavaScript中怎么處理異步,相信很多沒(méi)有經(jīng)驗的人對此束手無(wú)策,為此本文總結了問(wèn)題出現的原因和解決方法,通過(guò)這篇文章希望你能解決這個(gè)問(wèn)題。

一、回調函數

回調是一個(gè)函數被作為一個(gè)參數傳遞到另一個(gè)函數里,在那個(gè)函數執行完后再執行?;卣{函數是異步編程最基本的方法,其優(yōu)點(diǎn)是簡(jiǎn)單、容易理解和部署;缺點(diǎn)是容易產(chǎn)生回調地獄。

ajax('XXX1', () => {   // callback 函數體   ajax('XXX2', () => {     // callback 函數體     ajax('XXX3', () => {       // callback 函數體     })   }) })

這就是所謂的回調地獄,回調地獄帶來(lái)的負面作用有以下幾點(diǎn):

  • 代碼臃腫,可讀性差,可維護性差。

  • 代碼復用性差。

  • 容易滋生 bug。

  • 只能在回調里處理異常。

二、事件監聽(tīng)

這種方式,異步任務(wù)的執行不取決于代碼的順序,而取決于某個(gè)事件是否發(fā)生。

(1) 普通方式

f1.on('done', f2);

上面這行代碼的意思是,當f1發(fā)生done事件,就執行f2。

(2) onclick方法

element.onclick=function(){    //處理函數 }  element.onclick=handler1; element.onclick=handler2; element.onclick=handler3; // 只有handler3會(huì )被添加執行

優(yōu)點(diǎn):寫(xiě)法兼容到主流瀏覽器;

缺點(diǎn):當同一個(gè)element元素綁定多個(gè)事件時(shí),只有最后一個(gè)事件會(huì )被添加

(3) addEvenListener

elment.addEvenListener("click",handler1,false); elment.addEvenListener("click",handler2,false); elment.addEvenListener("click",handler3,false);

該方法的第三個(gè)參數是一個(gè)布爾值:當為false時(shí)表示由里向外,true表示由外向里。

三、發(fā)布/訂閱模式

我們假定,存在一個(gè)"信號中心",某個(gè)任務(wù)執行完成,就向信號中心"發(fā)布"(publish)一個(gè)信號,其他任務(wù)可以向信號中心"訂閱"(subscribe)這個(gè)信號,從而知道什么時(shí)候自己可以開(kāi)始執行。這就叫做"發(fā)布/訂閱模式"(publish-subscribe  pattern)

首先,f2向信號中心jQuery訂閱done信號。

jQuery.subscribe('done', f2);

然后,f1進(jìn)行如下改寫(xiě):

function f1() {   setTimeout(function () {     jQuery.publish('done');   }, 1000); }

f1執行完成后,向信號中心jQuery發(fā)布done信號,從而引發(fā)f2的執行。f2完成執行后,可以取消訂閱(unsubscribe)

jQuery.unsubscribe('done', f2);

這種方式的優(yōu)點(diǎn):可以通過(guò)查看“消息中心”,了解存在多少信號、每個(gè)信號有多少訂閱者,從而監控程序的運行。

四、promise

以上都是ES6之前的異步處理方式。ES6之后出現了promise。它是異步編程的一種解決方案,比傳統的解決方案(回調函數)——更合理和更強大。

Promise 對象有以下兩個(gè)特點(diǎn)。

  • 對象的狀態(tài)不受外界影響。Promise  對象代表一個(gè)異步操作,有三種狀態(tài):pending(進(jìn)行中)、fulfilled(已成功)和rejected(已失敗)。只有異步操作的結果,可以決定當前是哪一種狀態(tài),任何其他操作都無(wú)法改變這個(gè)狀態(tài)。

  • 一旦狀態(tài)改變,就不會(huì )再變,任何時(shí)候都可以得到這個(gè)結果

1. 基本用法

(1) ES6 規定,Promise 對象是一個(gè)構造函數,用來(lái)生成 Promise 實(shí)例。

const promise = new Promise((resolve, reject) => {   if (/* 異步操作成功 */){     resolve(success)   } else {     reject(error)   } })

Promise接收一個(gè)函數作為參數,函數里有resolve和reject兩個(gè)參數:

  • resolve方法的作用是將Promise的pending狀態(tài)變?yōu)閒ullfilled,在異步操作成功之后調用,可以將異步返回的結果作為參數傳遞出去。

  • reject方法的作用是將Promise的pending狀態(tài)變?yōu)閞ejected,在異步操作失敗之后調用,可以將異步返回的結果作為參數傳遞出去。

  • 他們之間只能有一個(gè)被執行,不會(huì )同時(shí)被執行,因為Promise只能保持一種狀態(tài)。

(2) Promise 實(shí)例生成以后,可以用then方法分別指定resolved狀態(tài)和rejected狀態(tài)的回調函數。

promise.then((success) => {   // 對應于上面的resolve(success)方法 }, (error) => {   // 對應于上面的reject(error)方法 }   // 還可以寫(xiě)成這樣 (推薦使用這種寫(xiě)法) promise.then((success) => {   // 對應于上面的resolve(success)方法 }).catch((error) => {   // 對應于上面的reject(error)方法 })

then(onfulfilled,onrejected)方法中有兩個(gè)參數,兩個(gè)參數都是函數:

  • 第一個(gè)參數執行的是resolve()方法(即異步成功后的回調方法)

  • 第二參數執行的是reject()方法(即異步失敗后的回調方法)(第二個(gè)參數可選)。

  • 它返回的是一個(gè)新的Promise對象。

(3) promise構造函數是同步執行的,then方法是異步執行的

const promise = new Promise((resolve, reject) => {   console.log(1)   resolve()   console.log(2) })  promise.then(() => {   console.log(3) })  console.log(4) // 1  2  4   3

2. Promise.finally()

Promise.finally()用于指定不管 Promise 對象最后狀態(tài)如何,都會(huì )執行的操作。

promise .then(result => {···}) .catch(error => {···}) .finally(() => {···});

3. Promise.all()

Promise.all()用于處理多個(gè)異步處理,比如說(shuō)一個(gè)頁(yè)面上需要等多個(gè) ajax 的數據回來(lái)才執行相關(guān)邏輯。

const p = Promise.all([p1, p2, p3]);

p的狀態(tài)由p1、p2、p3決定,分成兩種情況。

  • 只有p1、p2、p3的狀態(tài)都變成fulfilled,p的狀態(tài)才會(huì )變成fulfilled,此時(shí)p1、p2、p3的返回值組成一個(gè)數組,傳遞給p的回調函數。

  • 只要p1、p2、p3之中有一個(gè)被rejected,p的狀態(tài)就變成rejected,此時(shí)第一個(gè)被reject的實(shí)例的返回值,會(huì )傳遞給p的回調函數。

4. Promse.race()

Promse.race()就是賽跑的意思,Promise.race([p1, p2,  p3])里面哪個(gè)結果獲得的快,就返回那個(gè)結果,不管結果本身是成功狀態(tài)還是失敗狀態(tài)。

const p = Promise.race([p1, p2, p3])

上面代碼中,只要p1、p2、p3之中有一個(gè)實(shí)例率先改變狀態(tài),p的狀態(tài)就跟著(zhù)改變。那個(gè)率先改變的 Promise  實(shí)例的返回值,就傳遞給p的回調函數。

五、async/await

async/await是JavaScript為了解決異步問(wèn)題而提出的一種解決方案,許多人將其稱(chēng)為異步的終極解決方案。async 函數,就是  Generator 函數的語(yǔ)法糖。

相較于 Generator,Async 函數的改進(jìn)在于下面四點(diǎn):

  • 內置執行器。Generator 函數的執行必須依靠執行器,而 Aysnc 函數自帶執行器,調用方式跟普通函數的調用一樣。

  • 更好的語(yǔ)義。async 和 await 相較于 * 和 yield 更加語(yǔ)義化。

  • 更廣的適用性。co 模塊約定,yield 命令后面只能是 Thunk 函數或 Promise對象。而 async 函數的 await 命令后面可以是  Promise 或者原始類(lèi)型(Number,string,boolean,但這時(shí)等同于同步)。

  • 返回值是 Promise。async 函數返回值是 Promise 對象,比 Generator 函數返回的 Iterator 對象方便,可以直接使用  then() 方法進(jìn)行調用。

1. 使用規則

(1) 凡是在前面添加了async的函數在執行后都會(huì )自動(dòng)返回一個(gè)Promise對象

async function test() {      }  let result = test() console.log(result)  //即便代碼里test函數什么都沒(méi)返回,我們依然打出了Promise對象

(2) await必須在async函數里使用,不能單獨使用

function test() {   let result = await Promise.resolve('success')   console.log(result) }  test()   //執行以后會(huì )報錯

2. await 在等什么

  • 如果await等到的不是一個(gè)promise對象,那跟著(zhù)的表達式的運算結果就是它等到的東西;

  • 如果是一個(gè)promise對象,await會(huì )阻塞后面的代碼,等promise對象resolve,得到resolve的值作為await表達式的運算結果

  • 雖然await阻塞了,但await在async中,async不會(huì )阻塞,它內部所有的阻塞都被封裝在一個(gè)promise對象中異步執行 

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自互聯(lián)網(wǎng)轉載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權請聯(lián)系QQ:712375056 進(jìn)行舉報,并提供相關(guān)證據,一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容。

无码专区久久综合久中文字幕| 欧美性XXXXX极品少妇直播| 国产免费丝袜调教视频| 亚洲中文波霸中文字幕| 丰满人妻被黑人猛烈进入| 久久精品WWW人人做人人爽|