【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 字典中的数据渲染到页面上

相关推荐
用户92108026286几秒前
3. 给 Bubble 新增一个 Agent Variant
前端
jason成都3 分钟前
ignav-next|Java 层封装 GNSS/INS 组合导航框架,隔离 RTKLIB 与 INS 内核,双模块独立演进、最小侵入
java·开发语言
抓不住时间的沙4 分钟前
butterfly主题美化,打造属于自己的个性博客
java·开发语言·前端·javascript·node.js·github
kyriewen14 分钟前
前端切图仔被 AI 新闻淹死的第 N 天,我用 TRAE Work 定时任务救了自己
前端·人工智能·trae
京东云开发者16 分钟前
【全栈实践】第一个 AI Agent 项目:从零搭建 AI 音频创作助手(高级篇)
前端·agent·音视频开发
MarkHD18 分钟前
Stable Diffusion入门第19-20天:保存与分享你的工作流——第一阶段收官,从“能用”到“可复用”
java·开发语言·stable diffusion
云水初26 分钟前
【agent篇】RAG 知识库构建避坑指南
开发语言·python·学习·agent·rag
2019一路前行28 分钟前
Python 函数、循环语句
开发语言·python
AbrahamCS33 分钟前
从角色协同到可运行图:Graph Engineer 与多智能体编排
前端·人工智能·智能体
BigTopOne43 分钟前
VS Code IntelliSense 配置(解决 #include 找不到的报红)
前端