<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          5 個JavaScript Util 函數(shù)為你的應(yīng)用程序增添趣味

          共 4303字,需瀏覽 9分鐘

           ·

          2021-09-14 11:25

          英文 | https://betterprogramming.pub/5-javascript-promises-util-functions-to-spice-up-your-apps-665affca236c

          翻譯 | 小愛


          1、 模擬延遲

          有時我們需要模擬某些動作之間的特定延遲。使用以下代碼就很容易實現(xiàn):

          function delay(timeout) {   return new Promise(        (resolve) => {            const timeoutHandle =                 setTimeout(() => {                    clearTimeout(timeoutHandle);                    resolve()                                 }, timeout);   });}

          這個util函數(shù)的用法如下:

          async function(){   console.log('The first log');   await delay(1000);   console.log('The second log with 1000 ms delay')}

          作為輸出,我們將立即看到第一個日志,第二個日志在 1000 毫秒后出現(xiàn)。

          2、分解長期運行的任務(wù)

          由于 JS 是一種單線程語言,我們可能會遇到 UI 延遲或無響應(yīng)的服務(wù)器來處理新的即將到來的請求。它通常發(fā)生在應(yīng)用程序試圖處理長時間運行的任務(wù)時。

          有時,需要一個工具完成將長時間運行的任務(wù)進行拆分為多個塊,以便有機會完成另一個應(yīng)用程序代碼。這是代碼:

          function nextFrame() {     const nextTick = requestAnimationFrame || setImmediate.      return new Promise((res) => nextTick(() => res()))}

          這個util函數(shù)的用法:

          async longRunningTask(){   let step = 0;   while(true){        if (++step % 5 === 0){             await nextFrame();        }   }}longRunningTask();console.log('The first log')

          盡管我們運行了一個無限循環(huán),但這個函數(shù)的第 5 步為處理其他應(yīng)用程序的代碼開辟了道路。

          3、為 Promise 添加超時限制

          如果某些操作正在使用 Promise 處理,那么使用以下代碼很容易為其添加超時限制:

          function addTimeoutToPromise(targetPromise, timeout) {   let timeoutHandle;   const timeoutLimitPromise = new Promise((res, rej) => {       timeoutHandle = setTimeout(           () => rej(new Error('Timeout exceeded')),           timeout       );   });   return Promise.race([targetPromise, timeoutLimitPromise])       .then((res) => {           clearTimeout(timeoutHandle);           return res;       });}

          這個util函數(shù)的用法如下圖所示:

          addTimeoutToPromise(     delay(1000).then(() => console.log('Completed')), 2000);// --> CompletedaddTimeoutToPromise(    delay(2000), 1000).catch((e) => console.error(e.message))// --> Timeout exceeded

          4、按順序完成 Promise

          假設(shè)我們有一個 API,它對可以同時完成的請求數(shù)量有限制。它迫使我們開發(fā)一種方法,允許一個接一個地完成一堆承諾。

          首先,與 Promise.all 不同,我們不能只將一個 promise 數(shù)組傳遞給我們的方法,因為一旦創(chuàng)建了 promise,所有這些都會立即完成。

          因此,我們的 util 函數(shù)應(yīng)該獲得一組函數(shù),這些函數(shù)可以按需創(chuàng)建承諾,我們可以控制這個承諾何時開始競爭,如下所示:

          function completeInSequence(promiseFactories: () => Promise<any>){    ...}

          從字面上看,我們需要構(gòu)建以下結(jié)構(gòu),它允許按順序完成承諾。下面是一些代碼來做到這一點:

          Promise.resolve()   .then(() => promiseFacrories[0]()   .then(() => promiseFactories[1]())   ...   .then(() => promiseFactories[N]())

          在這里, Promise.resolve 和 Array.reduce 發(fā)揮作用。Promise.resolve 通常用作構(gòu)建承諾鏈的起點。這是幫助解決此問題的代碼:

          function completeInSequence(promiseFactories: () => Promise<any>) {   return promiseFactories.reduce(      (chain, promiseFactory) => chain.then(()=> promiseFactory()),      Promise.resolve()   );}

          很簡單的實現(xiàn)。讓我們用以下內(nèi)容測試它:

          completeInSequence([   () => delay(1000).then(() => console.log('1')),   () => delay(1000).then(() => console.log('2')),   () => delay(1000).then(() => console.log('3'))])

          你將看到所有日志消息之間的間隔為 1000 毫秒。

          5、只同時完成 N 個 Promise

          我們考慮到使用 API 的帶寬是很酷的,但我認為它可能允許我們同時完成多個請求。

          好吧,和前面的例子一樣,我們?nèi)匀恍枰粋€創(chuàng)建 promise 的函數(shù),它提供了控制 promise 何時完成的機會。第二個變量是池的最大大小,它反映了可以同時處理的承諾數(shù)量。下面是一個例子:

          function completePromisesInPool(    promiseFactories: () => Promise<any>,    maxPoolSize: number) { .... }

          首先,函數(shù)應(yīng)該在我們需要開始完成N個promise的地方返回Promise。

          之后,只要任何一個運行承諾完成,就意味著我們在池中有一個空閑插槽,如果它仍然存在,另一個承諾可能會取代這個位置,否則解決包裝承諾。這是執(zhí)行此操作的函數(shù):

          function completePromisesInPool(    promiseFactories: () => Promise<any>,    maxPoolSize: number) {   return new Promise((res) => {      let nextPromise = 0;      const runPromise = () => {         nextPromise++;         if (nextPromise > promiseFactories.length) {            res();            return;         }         return promiseFactories[nextPromise-1]()              .then(() => runPromise())      }
          Array.from({length: maxPoolSize}) .map(() => runPromise()); })}

          讓我們使用以下內(nèi)容對其進行測試:

          completePromisesInPool([   () => delay(1000).then(() => console.log('1')),   () => delay(1000).then(() => console.log('2')),   () => delay(1000).then(() => console.log('3')),   () => delay(1000).then(() => console.log('4')),   () => delay(1000).then(() => console.log('5')),   () => delay(1000).then(() => console.log('6'))  ], 2)

          你將看到 console.log 以 1000 毫秒的間隔分批打印兩條消息。這是它的樣子:

          就是這個樣子。

          感謝你的閱讀。

          學(xué)習(xí)更多技能

          請點擊下方公眾號

          瀏覽 18
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲性爱二区 | 91人妻人人澡 | 色综合av在线 | AV中文字幕网站 | 国产91热爆TS人妖系列 |