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

相关推荐
Swift社区1 小时前
在 Swift 中实现字符串分割问题:以字典中的单词构造句子
开发语言·ios·swift
new出一个对象1 小时前
uniapp接入BMapGL百度地图
javascript·百度·uni-app
没头脑的ht1 小时前
Swift内存访问冲突
开发语言·ios·swift
没头脑的ht1 小时前
Swift闭包的本质
开发语言·ios·swift
wjs20241 小时前
Swift 数组
开发语言
你挚爱的强哥2 小时前
✅✅✅【Vue.js】sd.js基于jQuery Ajax最新原生完整版for凯哥API版本
javascript·vue.js·jquery
stm 学习ing2 小时前
FPGA 第十讲 避免latch的产生
c语言·开发语言·单片机·嵌入式硬件·fpga开发·fpga
y先森3 小时前
CSS3中的伸缩盒模型(弹性盒子、弹性布局)之伸缩容器、伸缩项目、主轴方向、主轴换行方式、复合属性flex-flow
前端·css·css3
前端Hardy3 小时前
纯HTML&CSS实现3D旋转地球
前端·javascript·css·3d·html
susu10830189113 小时前
vue3中父div设置display flex,2个子div重叠
前端·javascript·vue.js