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

相关推荐
Code_Solitude14 分钟前
c语言:二分法的完整补充
c语言·开发语言·算法
智鸟科技GemeOpen开发者智能设备22 分钟前
MQTT智能通断器GSCW1M2P · 开发者实战指南
开发语言·物联网·智能家居
青柠之夏cc1 小时前
前端拖拽功能原生实现,不引入拖拽库完成业务
开发语言·前端·python
ym hyd 1111 小时前
题库建立与考试系统源码 Java+SpringBoot+Vue3 前后分离
java·开发语言·vue.js·spring boot·毕设
OKkankan1 小时前
Python 高阶语法(一):高阶函数、闭包、lambda 与 functools——从底层真正理解装饰器
开发语言·python
geovindu2 小时前
rust: Facade Pattern
开发语言·后端·设计模式·rust·外观模式
liangshanbo12152 小时前
前端大文件切片上传怎么做?
前端
福大大架构师每日一题2 小时前
Rust 1.99.0发布:C 可变参数、裸函数、Cargo 配置、Rustdoc 性能与大量兼容性调整全解析
c语言·开发语言·rust
智鸟科技GemeOpen开发者智能设备2 小时前
平安校园 AI 智能实时告警系统 智鸟科技·GemeOpen + 谷华科技·融合创新方案白皮书
java·开发语言·python·物联网·智能家居
Wang's Blog2 小时前
Java框架 SpringCloud 快速入门: Feign 的自定义配置与日志级别
java·开发语言·spring cloud