如何在JavaScript/TypeScript中編寫更簡潔的兩階段承諾?
P粉401527045
P粉401527045 2024-02-25 22:20:55
0
1
381

我這裡的用例:

  • 如果資源立即可用,則傳回它
  • 如果資源尚不可用,則顯示模式或載入指示器,然後等待其準備就緒
  • 模態邏輯必須與承諾/請求邏輯解耦

#有更好的設計模式嗎?

let twoStagePromise = (state: boolean): Promise<{ ready: boolean, wait: Promise<any>; }> => {
    return new Promise((resolve, reject) => {
        try {
            if (state) {
                resolve({
                    ready: true,
                    wait: new Promise((resolve, reject) => {
                        resolve([1, 2, 3]);
                    })
                });
            } else {
                resolve({
                    ready: false,
                    wait: new Promise((resolve, reject) => {
                        setTimeout(() => { resolve([1, 2, 3]); }, 1000);
                    })
                });
            }
        } catch (e) {
            reject(e);
        }
    });
};

twoStagePromise(false).then((data) => {
    if (!data.ready) {
        console.log('loading...');
    }
    return data.wait;
}).then((result) => {
    console.log("recieved result", result);
}).catch((error) => {
    console.log("try-catch failed or inner promise failed")
});

閱讀了一些評論後,我大大簡化了程式碼:

let twoStagePromise = (state: boolean): Promise<number[] | Promise<number[]>> => {
    return new Promise((resolve, reject) => {
        try {
            if (state) {
                resolve([1, 2, 3]);
            } else {
                resolve(new Promise((resolve) => setTimeout(() => { resolve([1,2,3])  }, 1000)))
            }
        } catch (e) {
            reject(e);
        }
    });
};

twoStagePromise(false).then((dataOrPromise) => {
    if (dataOrPromise instanceof Promise) {
        console.log('loading...');
    }
    return dataOrPromise // continue the promise chain by returning the promise or data
}).then((result) => {
    console.log("recieved result", result);
}).catch((error) => {
    console.log("try-catch failed or inner promise failed", error)
});

P粉401527045
P粉401527045

全部回覆(1)
P粉270842688

您可以建立一個明確傳回值或其承諾的函數。無論如何你都可以輕鬆地 await 了。若要檢查結果是否同步,請使用 result instanceof Promise

type Awaitable = T | Promise
function maybeImmediate(
    call: () => Awaitable,
    tryImmediate: boolean,
): Awaitable {
    if (tryImmediate) {
        try {
            return call(); // you don't know if it's T or Promise actually
        } catch (err) {
            // choose the one you want
            if (Math.random() > 0.5) {
                throw err;
            } else {
                return Promise.reject(err)
            }
        }
    } else {
        // make sure it's a promise
        return Promise.resolve().then(() => call())
    }
};

let cache: Record = {};
function getCached(url: string): Awaitable {
    if (cache[url]) return cache[url];
    return new Promise(r => {
        setTimeout(() => r('result of ' url), 1000)
    }).then(v => { cache[url] = v; return v })
}
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!