Promise串行的六种方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
/**
题1:
let arr = [
new Promise(res=>{
setTimeout(()=>{
res(1)
},1000)
}),
new Promise(res=>{
setTimeout(()=>{
res(2)
},1000)
}),
new Promise(res=>{
setTimeout(()=>{
res(3)
},1000)
})]
function iteratorPromise(arr){
//补充代码
}
iteratorPromise(arr);
复制代码
先定义一个Promise的数组,串行执行它们,最后实现如下的输出
思路:那么要怎么实现串行显示呢?其实只要将它们用.then链接起来就好了,就是一个上一个Promise.then里面返回下一个Promise;
*/
function iteratorPromise(arr) {
for (let i = 0; i < arr.length; i++) {
arr[i].then(num => {
console.log(num);
return arr[i + 1];
})
}
}
// iteratorPromise(arr);
</script>
<script>
// 题2:
/**
let arr = [()=>{
return new Promise(res=>{
setTimeout(()=>{
console.log("run", Date.now());
res()
},1000)
})
},()=>{
return new Promise(res=>{
setTimeout(()=>{
console.log("run", Date.now());
res()
},1000)
})
},()=>{
return new Promise(res=>{
setTimeout(()=>{
console.log("run", Date.now());
res()
},1000)
})
}]
*/
// 方法2: 使用promise后接 then 来实现串行
function iteratorPromise1(arr) {
let res = Promise.resolve();
arr.forEach(element => {
res = res.then(() => element());
});
}
// // 方法3: 使用 await 来实现串行
function iteratorPromise2(arr) {
arr.forEach(async element => await element());
}
// iteratorPromise2(arr1);
</script>
<script>
/**
题三:
const arr = [
Promise.resolve('1'),
new Promise(function (resolve, reject) {
setTimeout(resolve, 2000, '2')
}),
Promise.resolve('3'),
new Promise(function (resolve, reject) {
setTimeout(resolve, 3000, '4')
}),
Promise.resolve('5'),
]
*/
const arr = [
Promise.resolve('1'),
new Promise(function (resolve, reject) {
setTimeout(resolve, 2000, '2')
}),
Promise.resolve('3'),
new Promise(function (resolve, reject) {
setTimeout(resolve, 3000, '4')
}),
Promise.resolve('5')
]
function iteratorPromise3(arr) {
arr.forEach(async ele => await ele);
}
iteratorPromise3(arr3);
</script>
<script>
// 看这一篇,方法汇总
/**
使用Array.prototype.reduce、使用async + 循环 + await、
或者使用新出的for await of
*/
// 方法1 reduce
arr.reduce((prev, curr) => {
return prev.then(() => delay(curr));
}, Promise.resolve())
// 方法2 async + 循环 + await
async function test() {
for (let val of arr) {
await delay(val);
}
}
test();
// 方法3:方法1的变种
let p = Promise.resolve();
for (let val of arr) {
p = p.then(() => delay(v));
}
// 方法4:递归
function dispatch(i, p = Promise.resolve()) {
if (!arr[i]) return Promise.resolve();
return p.then(() => dispatch(i + 1, delay(arr[i])));
}
// 方法5: for await of
/**
通过查阅了for await of的规则,其实for await of和for of规则类似,
只需要实现一个内部[Symbol.asyncIterator]方法即可
*/
function createAsyncIterable(arr) {
return {
[Symbol.asyncIterator]() {
return {
i: 0,
next() {
if (this.i < arr.length) {
return delay(arr[this.i]).then(() => ({ value: this.i++, done: false }));
}
return Promise.resolve({ done: true });
}
};
}
}
}
(async function () {
for await (i of createAsyncIterable(arr)) { }
})();
// 方式6. generator
function* gen() {
for (const v of arr) {
yield delay(v)
}
}
function run(gen) {
const g = gen()
function next(data) {
const result = g.next(data)
if (result.done) return result.value
result.value.then(function (data) {
next(data)
})
}
next()
}
run(gen)
</script>
</body>
</html>
可参考
https://juejin.cn/post/6844903801296519182