【Promise】聊聊任务队列

历史小剧场

现实是残酷的,而今这个世界,要活下去,必死需要更大的勇气。

但崇祯的死,并非懦弱,而是一种态度,负责人的态度。

我说过,所谓王朝,跟公司单位差不多,单位出了事,领导要负责任,降级、扣工资、辞退,当然,也包括自尽。

崇祯决定自尽,他打算用这种方式,表达他的如下观点:

一、绝不妥协;

二、绝不当俘虏;

三、尊严。 ---《明朝那些事儿》

Promise队列原理

Promise队列就是来了一个任务一定要等上一个任务做完才继续做下一个任务。

如下代码所示:

js 复制代码
new Promise((resolve) => {
    resolve(1)
}).then(value => {
    return new Promise((resolve) => {
        setTimeout(() => {
            console.log(value)
            resolve(2)
        }, 1000)
    })
}).then(value => {
    return new Promise((resolve) => {
        setTimeout(() => {
            console.log(value)
            resolve()
        }, 1000)
    })
})

运行上诉代码,我们可以看到

  • 过了1秒中之后打印 1
  • 然后,又过了1秒钟后打印 2

map()实现Promise队列

案例一

js 复制代码
const queue = (nums) => {
    let promise = Promise.resolve()
    nums.map(num => {
        promise = promise.then(_ => {
            return new Promise(resolve => {
                setTimeout(() => {
                    console.log(num)
                    resolve()   // 改变状态
                }, 1000)
            })
        })
    })
}

queue([1, 2, 3, 4, 5])

运行如上代码,会每隔1秒钟打印 1 2 3 4 5

案例二

js 复制代码
const queue2 = (tasks) => {
    let promise = Promise.resolve()
    tasks.map(task => {
        promise = promise.then(_ => {
            return task()
        })
    })
}

const task1 = () => {
    return new Promise(resolve => {
        setTimeout(() => {
            console.log("task1")
            resolve()
        }, 1000)
    })
}
const task2 = () => {
    return new Promise(resolve => {
        setTimeout(() => {
            console.log("task2")
            resolve()
        }, 1000)
    })
}
queue2([task1, task2])

运行如上代码,会每隔1秒钟执行 task1和task2

reduce()实现Promise队列

js 复制代码
const reduceQueue = (nums) => {
    nums.reduce((promise, num) => {
        return promise.then(_ => {
            return new Promise(resolve => {
                setTimeout(() => {
                    console.log(num)
                    resolve()
                }, 1000)
            })
        })
    }, Promise.resolve())
}

reduceQueue([1, 2, 3, 4, 5])

使用Promise队列渲染数据

这里,假如我们想后端请求字典, 后端请求地址为 http://xxx

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script src="./js/ajax.js"></script>
    <script>
        class Dict {
            query(dictType) {
                return ajax(`http://xxx&dict=${dictType}`)
            }
            // 使用队列
            render(dictTypeList) {
                dictTypeList.reduce((promise, dictType_) => {
                    return promise.then(_ => {
                        return this.query(dictType_)
                    }).then(dicts => {
                        this.view(dicts.data)
                    })
                }, Promise.resolve())
            }   
            view(dicts) {
                console.log("dicts => ", dicts)
                return new Promise(resolve => {
                    const frag = document.createDocumentFragment();
                    dicts.forEach(dictItem => {
                        const h4 = document.createElement("h4")
                        h4.textContent = dictItem
                        frag.appendChild(h4)
                    })
                    document.body.appendChild(frag)
                    resolve()
                })
            }
        }

        new Dict().render(['dict_approval_number_type', 'dict_pub_code'])
    </script>
</body>
</html>

ajax文件

js 复制代码
class ParamError extends Error {
    constructor(msg) {
        super(msg)
        this.name = 'ParamError'
    }
}

class HttpError extends Error {
    constructor(msg) {
        super(msg)
        this.name = 'HttpError'
    }
}

function ajax(url) {
    // 自定义错误处理
    if (!/^http/.test(url)) {
        throw new ParamError("请求地址格式错误")
    }
    return new Promise((resolve, reject) => {
        let xhr = new XMLHttpRequest();
        xhr.open("POST", url)
        xhr.send()
        xhr.onload = function () {
            if (this.status === 200) {
                resolve(JSON.parse(this.response))
            } else if (this.status === 4) {
                // 自定义错误处理
                reject(new HttpError("响应内容不存在"))
            } else {
                reject("加载失败")
            }
        }
        xhr.onerror = function () {
            reject(this)
        }
    })
}

在这个案例,首先会将 dict_approval_number_type 字典中的数据渲染到页面上,然后再将 dict_pub_code 字典中的数据渲染到页面上

相关推荐
指令集梦境几秒前
图解:单调栈算法模板(Java语言)
java·开发语言·算法
乘风gg1 分钟前
手把手带你实践历时一年总结的 AI Code Review 最佳工作流!
前端·ai编程·cursor
禅思院1 分钟前
POST请求发两次?一次讲透CORS预检机制,面试不再翻车
前端·架构·前端框架
IT_陈寒3 分钟前
SpringBoot自动配置这么智能,为啥我写的Bean注入不了?
前端·人工智能·后端
LT10157974446 分钟前
2026年Web自动化测试工具选型指南:多浏览器兼容解决方案
前端·测试工具·自动化
小灰灰搞电子9 分钟前
C++ boost::circular_buffer 详解:原理、用法与实战
开发语言·c++·boost
HYCS9 分钟前
用pixi.js实现fabric.js(七):框选、ActiveObject和控制点
前端·javascript·canvas
云浪15 分钟前
手把手教你用 fetch 读取 SSE 流,给 AI 聊天加上打字机效果
前端·javascript·vue.js
Csvn26 分钟前
Tailwind 动态拼接类名失效?JIT 引擎正在"静态分析"你
前端