以fetch为例详解如何消除js异步的传染性

作者:闭包旅人时间:2026-10-31 09:13:47浏览:351

本文通过fetch接口请求示例,深入解析JavaScript中异步操作“传染性”的产生机制。针对函数链式依赖导致所有调用者被迫变为异步的问题,提出了一种通过自定义fetch拦截错误并同步触发后续逻辑的解决方案。文章提供了具体的代码实现,展示如何将异步函数改造为同步形式,从而消除异步状态的传播,提升代码的可读性与执行效率。

如何解决传染性

在开发过程中,若某个函数需调用内部接口以完成其功能,且该函数又依赖于其他异步函数,这将导致整个调用链中的每个函数都被迫变为异步函数。面对这种异步状态的蔓延,我们需要寻找有效的解决策略。以下通过具体示例进行说明:

// 接口请求
        async function getList() {
            return await fetch('/list.json').then(res => res.json())
        }
        async function task1() {
            return await getList()
        }
        async function task2() {
            return await task1()
        }
        async function task3() {
            return await task2()
        }
        // 执行task3。获取到了getList的返回值
        console.log(task3().then(res => console.log(res)));

从上述代码可以看出,由于getList函数是异步的,这导致整个调用池中的所有相关函数都随之变成了异步函数。

那么,有什么办法能让其消除此异步形式呢?

一种可行的方案是将所有函数改造成同步函数。具体做法是自定义一个fetch方法,通过拦截报错并继续调用自身的异步函数,如果返回正确值则触发其包含的下一步实现。

具体实现代码如下:

function getList() {
            // 此处发送一个异步请求
            return fetch('/list.json')
        }
        function task1() {
            return getList()
        }
        function task2() {
            return task1()
        }
        function task3() {
            return task2()
        }
        /* 我们先写一个main函数  */
        function main() {
            const task3Run = task3()
            console.log(task3Run)
        }
        function run(fn) {
            /* 判断是否为promise函数 */
            const cache = []
            let i = 0
            const _originalFetch = window.fetch
            window.fetch = (...args) => {
                /* 发送请求,且报错 */
                /* 判断缓存如果存在,则交付缓存 */
                if (cache[i]) {
                    if (cache[i].status == 'fulfillled') {
                        return cache[i].data
                    } else if (cache[i].status == 'rejected') {
                        throw cache[i].err
                    }
                }
                const result = {
                    status: 'pending',
                    data: null,
                    err: null
                }
                cache[i++] = result
                const prom = _originalFetch(...args)
                    .then(res => res.json())
                    .then((resolve)=> {
                        result.status = 'fulfillled'
                        result.data = resolve
                    }, (inject) => {
                        result.status = 'rejected'
                        result.err = inject
                    })
                // 报错
                throw prom
            }
            try {
                fn()
            } catch (err) {
                if (err instanceof Promise) {
                    const reRun = () => {
                        i = 0;
                        fn()
                    }
                    err.then(reRun, reRun)
                }
            }
        }
        run(main)

以上就是以fetch为例详解如何消除js异步的传染性的详细内容,更多关于fetch消除js异步传染性的资料请关注本站其它相关文章!

作者最新文章