处理嵌套承诺中的所有承诺拒绝?

发布于 2025-02-11 01:55:34 字数 3545 浏览 1 评论 0原文

我正在使用Promise.race,所以我可以暂时out fetch通话。在不存在的API端点的测试期间,我会遇到“未手持的承诺拒绝”错误。该代码应该构架。log曾经发生任何故障。我在哪里不处理承诺拒绝?仅供参考,主要功能是功能检索

window.path = "http://localhost:3000/records";

function isPrimary(color)  {

    let colorIsPrimary = false;
    (color.startsWith("red") || color.startsWith("blue") || color.startsWith("yellow")) ? colorIsPrimary = true : null;
    return colorIsPrimary;

}

function transformData(records,page) {

    const transformedData = {
        "ids" : [],
        "open": [],
        "closedPrimaryCount": 0,
        "previousPage": null,
        "nextPage": null
    }

    let closedPrimaryCount = 0;

    records.forEach((record, index) => {

        if (index < 10) {

            transformedData.ids.push(record.id);

            record["isPrimary"] = false;
            isPrimary(record.color) ? record.isPrimary = true : null;
        
            record.disposition == "open" ? transformedData.open.push(record) : null;

            if (record.disposition == "closed") {
                isPrimary(record.color) ? closedPrimaryCount++ : null;   
            }

        }

    })

    transformedData.closedPrimaryCount = closedPrimaryCount;

    let previousPage = null;
    page > 1 ? previousPage = page - 1 : null;
    transformedData.previousPage = previousPage;

    let nextPage = null;
    records.length > 10 ? nextPage = page + 1 : null;
    transformedData.nextPage = nextPage;

    return transformedData;
   
}

function promiseTimeout(promise, ms) {

    let timeout = new Promise((resolve, reject) => {
        let timeoutID = setTimeout(() => {
            clearTimeout(timeoutID);
            reject("fetch failed - timeout");
        }, ms)
    })

    return Promise.race([promise, timeout]);

}

function doFetch(url) {

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

        fetch(url)

        .then((response) => {

            if (!response.ok) {
      
                reject(new Error("fetch failed - non 200"));
      
            }

            response.json()
        
            .then((records) => {

                resolve(records);

            })

            .catch((error) => {

                reject(new Error("fetch failed - error from response.json"));
            
            })    

        })

        .catch((error) => {

            reject(new Error("fetch failed - error from fetch"));
        
        })

    }) 

}

function retrieve({page = 1, colors = ["red", "brown", "blue", "yellow", "green"], thetest = false, windowPath = window.path} = {}) { 

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

        !thetest ? windowPath = "http://localhost:3000/records" : null;

        // limit set to 11 so we can determine nextPage
        const limit = "11";

        const offset = "" + ((page * 10) - 10);

        let colorArgs = "";
        colors.forEach((color, index) => {
            colorArgs = colorArgs + "&color[]=" + color; 
        });

        const requestQuery = `limit=${limit}&offset=${offset}${colorArgs}`;
        
        const requestURL = new URI(windowPath);
        requestURL.query(requestQuery);

        const promiseRace = promiseTimeout(doFetch(requestURL.toString()), 4000);

        promiseRace.then((records) => {

            const transformedData = transformData(records, page);

            resolve(transformedData);

        })

        promiseRace.catch((error) => {

            console.log(error);

        })        

    });

};

export default retrieve;

I'm using Promise.race so I can time out the fetch call. During a test to an API endpoint that doesn't exist, I'm getting an "Unhandled promise rejection" error. The code is supposed to console.log once upon any failure. Where am I not handling the promise rejection? FYI the main function is function Retrieve

window.path = "http://localhost:3000/records";

function isPrimary(color)  {

    let colorIsPrimary = false;
    (color.startsWith("red") || color.startsWith("blue") || color.startsWith("yellow")) ? colorIsPrimary = true : null;
    return colorIsPrimary;

}

function transformData(records,page) {

    const transformedData = {
        "ids" : [],
        "open": [],
        "closedPrimaryCount": 0,
        "previousPage": null,
        "nextPage": null
    }

    let closedPrimaryCount = 0;

    records.forEach((record, index) => {

        if (index < 10) {

            transformedData.ids.push(record.id);

            record["isPrimary"] = false;
            isPrimary(record.color) ? record.isPrimary = true : null;
        
            record.disposition == "open" ? transformedData.open.push(record) : null;

            if (record.disposition == "closed") {
                isPrimary(record.color) ? closedPrimaryCount++ : null;   
            }

        }

    })

    transformedData.closedPrimaryCount = closedPrimaryCount;

    let previousPage = null;
    page > 1 ? previousPage = page - 1 : null;
    transformedData.previousPage = previousPage;

    let nextPage = null;
    records.length > 10 ? nextPage = page + 1 : null;
    transformedData.nextPage = nextPage;

    return transformedData;
   
}

function promiseTimeout(promise, ms) {

    let timeout = new Promise((resolve, reject) => {
        let timeoutID = setTimeout(() => {
            clearTimeout(timeoutID);
            reject("fetch failed - timeout");
        }, ms)
    })

    return Promise.race([promise, timeout]);

}

function doFetch(url) {

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

        fetch(url)

        .then((response) => {

            if (!response.ok) {
      
                reject(new Error("fetch failed - non 200"));
      
            }

            response.json()
        
            .then((records) => {

                resolve(records);

            })

            .catch((error) => {

                reject(new Error("fetch failed - error from response.json"));
            
            })    

        })

        .catch((error) => {

            reject(new Error("fetch failed - error from fetch"));
        
        })

    }) 

}

function retrieve({page = 1, colors = ["red", "brown", "blue", "yellow", "green"], thetest = false, windowPath = window.path} = {}) { 

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

        !thetest ? windowPath = "http://localhost:3000/records" : null;

        // limit set to 11 so we can determine nextPage
        const limit = "11";

        const offset = "" + ((page * 10) - 10);

        let colorArgs = "";
        colors.forEach((color, index) => {
            colorArgs = colorArgs + "&color[]=" + color; 
        });

        const requestQuery = `limit=${limit}&offset=${offset}${colorArgs}`;
        
        const requestURL = new URI(windowPath);
        requestURL.query(requestQuery);

        const promiseRace = promiseTimeout(doFetch(requestURL.toString()), 4000);

        promiseRace.then((records) => {

            const transformedData = transformData(records, page);

            resolve(transformedData);

        })

        promiseRace.catch((error) => {

            console.log(error);

        })        

    });

};

export default retrieve;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

猥琐帝 2025-02-18 01:55:34

在Ggorlen的出色建议之后,我重构了这项更清洁(和测试)的代码:

async function getTransformedData(url,page) {

    try {

        const response = await fetch(url);

        if (response.ok) {

            const records = await response.json();

            const transformedData = transformData(records,page);

            return(transformedData);

        } else {

            throw new Error("failed");    

        }

    }

    catch(error) {

        console.log(error);

    }
    
    // getTransformedData
}


function retrieve({page = 1, colors = ["red", "brown", "blue", "yellow", "green"]} = {}) { 

    // limit set to 11 so we can determine nextPage
    const limit = "11";

    const offset = "" + ((page * 10) - 10);

    let colorArgs = "";
    colors.forEach((color, index) => {
        colorArgs = colorArgs + "&color[]=" + color; 
    });

    const requestQuery = `limit=${limit}&offset=${offset}${colorArgs}`;
    
    const requestURL = new URI(window.path);
    requestURL.query(requestQuery);

    return getTransformedData(requestURL.toString(),page);

};

After ggorlen's excellent advice, I refactored to this much cleaner (and test-passing) code:

async function getTransformedData(url,page) {

    try {

        const response = await fetch(url);

        if (response.ok) {

            const records = await response.json();

            const transformedData = transformData(records,page);

            return(transformedData);

        } else {

            throw new Error("failed");    

        }

    }

    catch(error) {

        console.log(error);

    }
    
    // getTransformedData
}


function retrieve({page = 1, colors = ["red", "brown", "blue", "yellow", "green"]} = {}) { 

    // limit set to 11 so we can determine nextPage
    const limit = "11";

    const offset = "" + ((page * 10) - 10);

    let colorArgs = "";
    colors.forEach((color, index) => {
        colorArgs = colorArgs + "&color[]=" + color; 
    });

    const requestQuery = `limit=${limit}&offset=${offset}${colorArgs}`;
    
    const requestURL = new URI(window.path);
    requestURL.query(requestQuery);

    return getTransformedData(requestURL.toString(),page);

};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文