【Promise】聊聊任务队列

历史小剧场

现实是残酷的,而今这个世界,要活下去,必死需要更大的勇气。
但崇祯的死,并非懦弱,而是一种态度,负责人的态度。
我说过,所谓王朝,跟公司单位差不多,单位出了事,领导要负责任,降级、扣工资、辞退,当然,也包括自尽。
崇祯决定自尽,他打算用这种方式,表达他的如下观点:
一、绝不妥协;
二、绝不当俘虏;
三、尊严。 —《明朝那些事儿》

Promise队列原理

Promise队列就是来了一个任务一定要等上一个任务做完才继续做下一个任务。
如下代码所示:

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队列

案例一

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

案例二

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队列

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

<!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文件

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

  • 17
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值