成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

九個Promises的必知高級用法

開發 前端
Promise 對象表示異步操作的最終完成(或失敗)及其結果值。

概述

Promise 對象表示異步操作的最終完成(或失敗)及其結果值。

Promise 始終處于以下狀態之一:

  • 待處理:初始狀態,既未實現也未拒絕。
  • 已實現:操作已成功完成。
  • 已拒絕:操作失敗。

與“舊式”回調不同,使用 Promises 具有以下約定:

  • 在當前事件循環完成之前,不會調用回調函數。
  • 即使異步操作完成(成功或失敗),之后通過 then() 添加的回調仍將被調用。
  • 可以通過多次調用 then() 來添加多個回調,它們將按照添加的順序執行。

Promises 的典型特征是鏈接。

一般用法

1.Promise.all([])

當數組中的所有 Promise 實例都成功時,它會按請求的順序返回成功結果數組。如果任何 Promise 失敗,它將進入失敗回調。

const p1 = new Promise((resolve) => {
    resolve(1);
});
const p2 = new Promise((resolve) => {
    resolve(1);
});
const p3 = Promise.resolve('ok');


// If all promises succeed, result will be an array of 3 results.
const result = Promise.all([p1, p2, p3]); 
// If one fails, the result is the failed promise's value.

2. Promise.allSettled([])

執行不會失敗;它返回與輸入數組中每個 Promise 實例的狀態相對應的數組。

const p1 = Promise.resolve(1);
const p2 = Promise.reject(-1);
Promise.allSettled([p1, p2]).then(res => {
    console.log(res);
});
// Output: 
/*
   [
    { status: 'fulfilled', value: 1 },
    { status: 'rejected', reason: -1 }
   ] 
*/

3. Promise.any([])

如果輸入數組中的任何 Promise 滿足條件,則返回的實例將變為滿足條件并返回第一個滿足條件的 Promise 的值。如果所有 Promise 均被拒絕,則將變為拒絕條件。

const p1 = new Promise((resolve, reject) => {
    reject(1);
});
const p2 = new Promise((resolve, reject) => {
    reject(2);
});
const p3 = Promise.resolve("ok");


Promise.any([p1, p2, p3]).then(
    (r) => console.log(r), // Outputs 'ok'
    (e) => console.log(e)
);

4. Promise.race([])

只要數組中的任何 Promise 改變狀態,race 方法的狀態就會隨之改變;第一個改變的 Promise 的值將傳遞給 race 方法的回調。

const p1 = new Promise((resolve) => {
    setTimeout(() => {
        resolve(10);
    }, 3000);
});
const p2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        throw new Error("I encountered an error");
    }, 2000);
});


Promise.race([p1, p2]).then(
    (v) => console.log(v), // Outputs 10
    (e) => console.log(e)
);

拋出異常不會改變競爭狀態;它仍然由 p1 決定。

高級用法

以下是 9 種高級用法,可幫助開發人員更高效、更優雅地處理異步操作。

1.并發控制

使用 Promise.all 允許并行執行多個 Promises,但要控制同時請求的數量,您可以實現并發控制功能。

const concurrentPromises = (promises, limit) => {
    return new Promise((resolve, reject) => {
        let i = 0;
        let result = [];
        const executor = () => {
            if (i >= promises.length) {
                return resolve(result);
            }
            const promise = promises[i++];
            Promise.resolve(promise)
                .then(value => {
                    result.push(value);
                    if (i < promises.length) {
                        executor();
                    } else {
                        resolve(result);
                    }
                })
                .catch(reject);
        };
        for (let j = 0; j < limit && j < promises.length; j++) {
            executor();
        }
    });
};

2. Promise 超時

有時,可能希望 Promise 在特定時間范圍內未解析時自動拒絕。這可以按如下方式實現。

const promiseWithTimeout = (promise, ms) =>
    Promise.race([
        promise,
        new Promise((resolve, reject) =>
            setTimeout(() => reject(new Error('Timeout after ' + ms + 'ms')), ms)
        )
    ]);

3. 取消 Promises

原生 JavaScript Promises 無法取消,但你可以通過引入可控中斷邏輯來模擬取消。

const cancellablePromise = promise => {
    let isCanceled = false;
    const wrappedPromise = new Promise((resolve, reject) => {
        promise.then(
            value => (isCanceled ? reject({ isCanceled, value }) : resolve(value)),
            error => (isCanceled ? reject({ isCanceled, error }) : reject(error))
        );
    });
    return {
        promise: wrappedPromise,
        cancel() {
            isCanceled = true;
        }
    };
};

4. Promise 數組的順序執行

有時您需要按順序執行一系列 Promise,確保前一個異步操作完成后再開始下一個操作。

const sequencePromises = promises =>
    promises.reduce(
        (prev, next) => prev.then(() => next()),
        Promise.resolve()
    );

5. Promise 的重試邏輯

當 Promise 因臨時錯誤而被拒絕時,您可能希望重試其執行。

const retryPromise = (promiseFn, maxAttempts, interval) => {
    return new Promise((resolve, reject) => {
        const attempt = attemptNumber => {
            if (attemptNumber === maxAttempts) {
                reject(new Error('Max attempts reached'));
                return;
            }
            promiseFn().then(resolve).catch(() => {
                setTimeout(() => {
                    attempt(attemptNumber + 1);
                }, interval);
            });
        };
        attempt(0);
    });
};

6. 確保 Promise 僅解析一次

在某些情況下,您可能希望確保 Promise 僅解析一次,即使多次調用 resolve。

const onceResolvedPromise = executor => {
    let isResolved = false;
    return new Promise((resolve, reject) => {
        executor(
            value => {
                if (!isResolved) {
                    isResolved = true;
                    resolve(value);
                }
            },
            reject
        );
    });
};

7. 使用 Promises 代替回調

Promises 通過替代回調函數,提供了一種更標準化、更方便的方式來處理異步操作。

const callbackToPromise = (fn, ...args) => {
    return new Promise((resolve, reject) => {
        fn(...args, (error, result) => {
            if (error) {
                reject(error);
            } else {
                resolve(result);
            }
        });
    });
};

8. 動態生成 Promise 鏈

在某些情況下,您可能需要根據不同的條件動態創建一系列 Promise 鏈。

const tasks = [task1, task2, task3]; // Array of asynchronous tasks


const promiseChain = tasks.reduce((chain, currentTask) => {
    return chain.then(currentTask);
}, Promise.resolve());

9. 使用 Promises 實現簡單的異步鎖

在多線程環境中,可以使用 Promises實現簡單的異步鎖,確保每次只有一個任務可以訪問共享資源。

let lock = Promise.resolve();


const acquireLock = () => {
    let release;
    const waitLock = new Promise(resolve => {
        release = resolve;
    });
    const tryAcquireLock = lock.then(() => release);
    lock = waitLock;
    return tryAcquireLock;
};

這段代碼不斷創建和解析 Promise,實現了一個簡單的 FIFO 隊列,確保只有一個任務可以訪問共享資源。

lock 變量表示當前是否有任務正在執行,始終指向正在進行的任務的 Promise。

acquireLock 函數請求執行權限并創建一個新的 Promise 以等待當前任務完成。

結論

Promise 是現代 JavaScript 異步編程不可或缺的一部分。

掌握它們的高級技巧將大大提高開發效率和代碼質量。通過上述各種方法,開發人員可以更自信地處理復雜的異步場景,編寫更易讀、更優雅、更健壯的代碼。

責任編輯:華軒 來源: web前端開發
相關推薦

2022-09-28 08:40:04

殺死一個終端進程

2011-01-18 11:07:28

2011-05-24 10:17:15

SEO

2018-04-23 11:24:37

多云模式公共云多云策略

2018-10-26 14:10:21

2009-09-11 10:33:52

招聘秘籍

2023-04-20 14:31:20

Python開發教程

2023-05-08 15:25:19

Python編程語言編碼技巧

2022-09-21 15:11:28

MySQL數據庫技巧

2011-05-31 14:48:31

PHP

2020-08-23 18:18:27

Python列表數據結構

2021-03-03 10:39:11

容器微服務IT

2024-01-08 18:05:19

PyCharm技巧功能

2024-01-23 18:49:38

SQL聚合函數數據分析

2022-07-20 00:03:10

Python列表字典推導

2019-10-08 16:24:33

Chrome瀏覽器

2024-12-04 10:19:49

2023-10-26 18:05:37

Git命令差異

2019-02-12 06:08:14

2023-09-20 22:52:12

Kubernetes快捷方式
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美一区在线视频 | 午夜精品一区二区三区三上悠亚 | 91极品视频| 国产精品永久久久久 | 国产激情自拍视频 | 免费观看成人性生生活片 | 国产精品久久久久久一区二区三区 | 91一区二区 | 成人黄页在线观看 | 国内精品久久久久久影视8 最新黄色在线观看 | 一级毛片在线播放 | 亚洲国产精选 | 日本中文字幕一区 | 久久久一区二区三区四区 | 成人影院在线 | 色综合天天网 | 国产亚洲欧美另类一区二区三区 | 精品国产一区二区国模嫣然 | 午夜手机在线视频 | 成人福利电影 | 日韩在线免费视频 | 国产精品1区 | 一区二区三区免费 | 欧美成人高清 | 国产精品久久久久久久久动漫 | www.精品国产 | 欧美日韩黄色一级片 | 成年人免费网站 | 亚洲国产成人精品女人久久久 | 欧美aⅴ| 欧美三级在线 | 日韩精品视频在线观看一区二区三区 | 中文字幕一区二区三区乱码图片 | 国内精品久久久久久 | 天天碰日日操 | 日韩一区二区av | 国产精品美女久久久久aⅴ国产馆 | 国产精品久久久久久亚洲调教 | 国产99视频精品免费视频7 | 国产精品视频免费观看 | 国产激情视频网站 |