狠狠色丁香婷婷综合尤物/久久精品综合一区二区三区/中国有色金属学报/国产日韩欧美在线观看 - 国产一区二区三区四区五区tv

LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

【JavaScript】掌握異步編程,看這里!

admin
2024年3月29日 23:43 本文熱度 1106

異步處理的概念

JavaScript 中的異步處理指的是在代碼執(zhí)行過程中,能夠不阻塞當(dāng)前線程并處理一些時(shí)間較長的操作。異步處理通常涉及到回調(diào)函數(shù)、Promise、async/await 等機(jī)制。

在 JavaScript 中,傳統(tǒng)的同步處理方式采用的是阻塞式的單線程模型。這種模型的缺點(diǎn)是當(dāng)一個(gè)任務(wù)被執(zhí)行時(shí),它會(huì)一直執(zhí)行到結(jié)束,期間如果有耗時(shí)的操作也會(huì)一直阻塞下去,直到任務(wù)執(zhí)行完畢,才會(huì)執(zhí)行后續(xù)的任務(wù)。這種方式會(huì)導(dǎo)致頁面卡死,體驗(yàn)非常不好。

因此,JavaScript 異步處理機(jī)制應(yīng)運(yùn)而生,它允許在代碼執(zhí)行過程中,執(zhí)行一些耗時(shí)的操作,而不會(huì)阻塞當(dāng)前線程。

回調(diào)函數(shù)

回調(diào)函數(shù)是一種很常見的異步編程模型,通過在異步操作完成后調(diào)用回調(diào)函數(shù)來通知異步操作已結(jié)束,從而執(zhí)行后續(xù)的任務(wù)。例如:

function fetchData(callback) {

  setTimeout(function() {

const data = { name: '張三', age: 20 };

    callback(data);

  }, 1000);

}


fetchData(function(data) {

  console.log(data);

});

在這個(gè)示例中,fetchData() 函數(shù)在完成數(shù)據(jù)加載后,調(diào)用回調(diào)函數(shù) callback() 并傳遞數(shù)據(jù)作為參數(shù)。當(dāng)數(shù)據(jù)加載完成后,控制器會(huì)跳轉(zhuǎn)到回調(diào)函數(shù)中執(zhí)行后續(xù)任務(wù)。

Promise

Promise 是一種比較流行的異步編程模型,它可以在異步操作完成后執(zhí)行一些回調(diào)操作,并將結(jié)果返回給請(qǐng)求方。Promise 代表了一個(gè)異步操作的最終完成(或失敗)及其結(jié)果值。例如:

function fetchData() {

  return new Promise(function(resolve, reject) {

    setTimeout(function() {

      const data = { name: '張三', age: 20 };

      resolve(data);

    }, 1000);

  });

}


fetchData().then(function(data) {

  console.log(data);

});

異步處理常見場景與處理策略

異步處理常見場景包括但不限于:

  1. 網(wǎng)絡(luò)請(qǐng)求:當(dāng)請(qǐng)求數(shù)據(jù)需要一定的時(shí)間才能返回時(shí),為了避免用戶體驗(yàn)受到影響,需要進(jìn)行異步處理。
  2. 定時(shí)任務(wù):定時(shí)執(zhí)行任務(wù),需要進(jìn)行異步處理。
  3. 事件處理:通過異步處理來避免事件處理函數(shù)執(zhí)行時(shí)間過長,導(dǎo)致頁面卡頓等問題。

  4. 大量數(shù)據(jù)處理:對(duì)于大量數(shù)據(jù)的處理,需要進(jìn)行異步處理,以免阻塞主線程。

JavaScript 引擎是單線程執(zhí)行的,也就是說同一時(shí)間內(nèi)只有一個(gè)任務(wù)在執(zhí)行。當(dāng)需要進(jìn)行異步操作時(shí),通常會(huì)使用回調(diào)函數(shù)。

假設(shè)我們有一個(gè)獲取用戶信息的異步函數(shù) getUserInfo,在信息獲取完成后需要調(diào)用相關(guān)回調(diào)函數(shù)。一種實(shí)現(xiàn)方式是將回調(diào)函數(shù)作為 getUserInfo 函數(shù)的第二個(gè)參數(shù)傳入,信息獲取完成后調(diào)用該函數(shù)。

function getUserInfo(userId, callback) {

  setTimeout(function() {

    const userInfo = {

      id: userId,

      name: "Tom",

      age: 25

    }

    callback(userInfo)

  }, 1000)

}


getUserInfo(1001, function(userInfo) {

  console.log(userInfo)

})

上述代碼首先調(diào)用 getUserInfo 函數(shù),該函數(shù)通過 setTimeout 模擬異步操作,等待 1 秒鐘后獲取用戶信息,并在信息獲取完成后調(diào)用傳入的回調(diào)函數(shù)。最后在回調(diào)函數(shù)中輸出用戶信息。

Promise A+ 規(guī)范

Promise 的狀態(tài)

一個(gè) Promise 的當(dāng)前狀態(tài)必須為以下三種狀態(tài)中的一種:等待態(tài)(Pending)執(zhí)行態(tài)(Fulfilled)和 拒絕態(tài)(Rejected)

  • 等待態(tài)(Pending)處于等待態(tài)時(shí),promise 需滿足以下條件:

    • 可以遷移至執(zhí)行態(tài)或拒絕態(tài)(fulfill、reject)

  • 執(zhí)行態(tài)(Fulfilled)處于執(zhí)行態(tài)時(shí),promise 需滿足以下條件:

    • 不能遷移至其他任何狀態(tài)

    • 必須擁有一個(gè)不可變的終值

  • 拒絕態(tài)(Rejected)處于拒絕態(tài)時(shí),promise 需滿足以下條件:

    • 不能遷移至其他任何狀態(tài)

    • 必須擁有一個(gè)不可變的原因

    • 這里的不可變指的是恒等(即可用 === 判斷相等),而不是意味著更深層次的不可變(譯者注:概指當(dāng) value 或 reason 不是基本值時(shí),只要求其引用地址相等,但屬性值可被更改)。


      面試官文檔 Promise A+ 規(guī)范時(shí),首先要提出的便是三個(gè)態(tài):pending、fulfilled、rejected


一個(gè) promise 必須提供一個(gè) then 方法以訪問其當(dāng)前值、終值和據(jù)因。

promise 的 then 方法接受兩個(gè)參數(shù):

promise.then(onFulfilled, onRejected);

其中,onFulfilled 和 onRejected 都是可選參數(shù)。

  • 如果 onFulfilled 不是函數(shù),其必須被忽略

  • 如果 onRejected 不是函數(shù),其必須被忽略

發(fā)布-訂閱模式

根據(jù) Promise A+ 規(guī)范,每次 then 返回的值也需要滿足 thenable,也就是說我們需要將 resolve 返回值使用 promise 包裹,在本例中就是需要將返回值包裝為新的 HePromise 對(duì)象。開發(fā)之前我們不妨先來看看 Promise 鏈?zhǔn)秸{(diào)用的示例:

const p = new Promise(resolve => resolve(1));

p.then(r1 => {

console.log(r1);

return 2;

})

  .then(r2 => {

console.log(r2);

return 3;

  })

  .then(r3 => {

console.log(r3);

  });

實(shí)現(xiàn)all方法

就是將傳入數(shù)組中的值 promise 化,然后保證每個(gè)任務(wù)都處理后,最終 resolve。示例如下:

class HePromise {

static all(promises: any[]) {

let index = 0;

const result: any[] = [];

const pLen = promises.length;

return new HePromise((resolve, reject) => {

      promises.forEach(p => {

        HePromise.resolve(p).then(

val => {

            index++;

            result.push(val);

if (index === pLen) {

              resolve(result);

            }

          },

err => {

if (reject) reject(err);

          },

        );

      });

    });

  }

}

編寫測試用例如下:

it('HePromise.all', done => {

  HePromise.all([1, 2, 3]).then(res => {

    expect(res).toEqual([1, 2, 3]);

    done();

  });

});

執(zhí)行測試,測試通過。

實(shí)現(xiàn)race方法

就是將傳入數(shù)組中的值 promise 化,只要其中一個(gè)任務(wù)完成,即可 resolve。示例如下:

class HePromise {

static race(promises: any[]): HePromise {

return new HePromise((resolve, reject) => {

      promises.forEach(p => {

        HePromise.resolve(p).then(

val => {

            resolve(val);

          },

err => {

if (reject) reject(err);

          },

        );

      });

    });

  }

}

編寫測試用例:

it('HePromise.race', done => {

  HePromise.race([11, 22, 33]).then(res => {

    expect(res).toBe(11);

    done();

  });

});

執(zhí)行測試,測試通過。

整體測試代碼情況如下:

async 與 await 用法及原理詳解

async function test() {

    const res = await Promise.resolve(1)

    return res

}

需要注意的是,使用 async、await 處理異步操作時(shí),需要注意異常的處理。

異常處理

通常我們使用 try、catch 捕獲 async、await 執(zhí)行過程中拋出的異常,就像這樣:

async function test() {

    let res = null

    try {

        const res = await Promise.resolve(1)

        return res

    } catch(e) {

        console.log(e)

    }

}

從零實(shí)現(xiàn)一個(gè)類似 async、await 的函數(shù)

promise+generator

function fn(nums) {

    return new Promise(resolve = >{

        setTimeout(() = >{

            resolve(nums * 2)

        },

        1000)

    })

}

function * gen() {

    const num1 = yield fn(1)

    const num2 = yield fn(num1)

    const num3 = yield fn(num2)

    return num3

}

function generatorToAsync(generatorFn) {

    return function() {

        return new Promise((resolve, reject) = >{

            const g = generatorFn() const next1 = g.next() next1.value.then(res1 = >{


                const next2 = g.next(res1) // 傳入上次的res1

                next2.value.then(res2 = >{


                    const next3 = g.next(res2) // 傳入上次的res2

                    next3.value.then(res3 = >{


                        // 傳入上次的res3

                        resolve(g.next(res3).value)

                    })

                })

            })

        })

    }

}


const asyncFn = generatorToAsync(gen)

asyncFn().then(res = >console.log(res)) // 3秒后輸出 8

自動(dòng)執(zhí)行

自動(dòng)執(zhí)行其實(shí)就是運(yùn)用遞歸,將生成器函數(shù)產(chǎn)生的數(shù)據(jù)不斷調(diào)用 next,直至執(zhí)行完成。

function getData(endpoint) {

  return new Promise(resolve => {

    setTimeout(() => {

      resolve(`Data received from ${endpoint}`)

    }, 2000)

  })

}


// 生成器函數(shù)

function* getDataAsync() {

  const result1 = yield getData('Endpoint 1')

  console.log(result1)

  const result2 = yield getData('Endpoint 2')

  console.log(result2)

  return 'All data received'

}


// 將生成器函數(shù)包裝成 Promise

function asyncToPromise(generatorFn) {

  const generator = generatorFn()


  function handleResult(result) {

    if (result.done) {

      return Promise.resolve(result.value)

    }


    return Promise.resolve(result.value)

      .then(res => handleResult(generator.next(res)))

      .catch(err => handleResult(generator.throw(err)))

  }


  try {

    return handleResult(generator.next())

  } catch (error) {

    return Promise.reject(error)

  }

}


asyncToPromise(getDataAsync).then(result => console.log(result))

總結(jié)

這里介紹了回調(diào)函數(shù)、Promise、async/await 等機(jī)制。其中涉及到JavaScript事件循環(huán)機(jī)制沒有展開分析,后續(xù)會(huì)總結(jié)相應(yīng)的通關(guān)手冊(cè)。 


該文章在 2024/3/29 23:46:43 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點(diǎn)晴ERP是一款針對(duì)中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對(duì)港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場、車隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場作業(yè)而開發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉儲(chǔ)管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲(chǔ)管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號(hào)管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved