英文:
How can I implement a more complex promise chain in javascript?
问题
我尝试实现一个更复杂的Promise链。流程和依赖关系如下:
- 启动 A、B 和 D
- 当 A 和 B 完成时启动 C
- 当 C 和 D 完成时启动 E
以下是模拟代码:
function test_p(name, sec) {
console.log(Date.now()-start,'Started ', name, " Sec: ", sec);
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(Date.now()-start,'Resolved ', name, " Sec: ", sec);
resolve(10);
}, sec * 1000);
});
}
start = Date.now();
p1 = test_p("A", 2)
.then((result) => { console.log(Date.now()-start, result); return result });
p2 = test_p("B", 5)
.then((result) => { console.log(Date.now()-start,result); return result });
pp1 = Promise.all([p1, p2])
.then((result) => { console.log(Date.now()-start,"p1-p2 started"); return result })
.then(() => { console.log(Date.now()-start,"p1-p2 done ") })
.then(() => {
p3 = test_p("C", 5)
.then((result) => { console.log(Date.now() - start, result); return result })
});
p4 = test_p("D", 7)
.then((result) => { console.log(Date.now()-start,result); return result });
pp2 = Promise.all([pp1, p3, p4])
.then((result) => { console.log(Date.now()-start,"pp1-p4 started"); return result });
这是控制台输出:0 'Started ' 'A' ' Sec: ' 2 VM10447:2 2
'Started ' 'B' ' Sec: ' 5 VM10447:2 2 'Started ' 'D' ' Sec: ' 7
Promise {} VM10447:5 2001 'Resolved ' 'A' ' Sec: ' 2
VM10489:3 2001 10 VM10447:5 5003 'Resolved ' 'B' ' Sec: ' 5 VM10489:5
5003 10 VM10489:7 5003 'p1-p2 started' VM10489:8 5003 'p1-p2 done '
VM10447:2 5003 'Started ' 'C' ' Sec: ' 5 VM10447:5 7002 'Resolved '
'D' ' Sec: ' 7 VM10489:14 7003 10 VM10489:16 7003 'pp1-p4 started'
VM10447:5 10004 'Resolved ' 'C' ' Sec: ' 5 VM10489:11 10004 10
我希望第二个Promise.all在C解决后大约在10000毫秒触发。
英文:
I try to implement a more complex promise chain.
Flow and dependencies:
- Start A, B and D
- Start C when A and B are done
- Start E when C and D are done
Here the simulation code:
function test_p(name, sec) {
console.log(Date.now()-start,'Started ', name, " Sec: ", sec);
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(Date.now()-start,'Resolved ', name, " Sec: ", sec);
resolve(10);
}, sec * 1000);
});
}
start = Date.now();
p1 = test_p("A", 2)
.then((result) => { console.log(Date.now()-start, result); return result });
p2 = test_p("B", 5)
.then((result) => { console.log(Date.now()-start,result); return result });
pp1 = Promise.all([p1, p2])
.then((result) => { console.log(Date.now()-start,"p1-p2 startet"); return result })
.then(() => { console.log(Date.now()-start,"p1-p2 done ") })
.then(() => {
p3 = test_p("C", 5)
.then((result) => { console.log(Date.now() - start, result); return result })
});
p4 = test_p("D", 7)
.then((result) => { console.log(Date.now()-start,result); return result });
pp2 = Promise.all([pp1, p3, p4])
.then((result) => { console.log(Date.now()-start,"pp1-p4 startet"); return result });
> This is the console protocol: 0 'Started ' 'A' ' Sec: ' 2 VM10447:2 2
> 'Started ' 'B' ' Sec: ' 5 VM10447:2 2 'Started ' 'D' ' Sec: ' 7
> Promise {<pending>} VM10447:5 2001 'Resolved ' 'A' ' Sec: ' 2
> VM10489:3 2001 10 VM10447:5 5003 'Resolved ' 'B' ' Sec: ' 5 VM10489:5
> 5003 10 VM10489:7 5003 'p1-p2 startet' VM10489:8 5003 'p1-p2 done '
> VM10447:2 5003 'Started ' 'C' ' Sec: ' 5 VM10447:5 7002 'Resolved '
> 'D' ' Sec: ' 7 VM10489:14 7003 10 VM10489:16 7003 'pp1-p4 startet'
> VM10447:5 10004 'Resolved ' 'C' ' Sec: ' 5 VM10489:11 10004 10
I wanted the second Promise.all to fire after C resolved around 10000 msec
答案1
得分: 1
你当前代码的问题在于 `pp1` 中最后一个 `.then()` 调用没有返回 `p3`。因此,你启动了计时器 C,但从未将其作为 `pp1` 的依赖项。要修复它,只需在那个 `.then()` 中返回 `p3`,如下所示:
```js
pp1 = Promise.all([p1, p2])
.then((result) => { console.log(Date.now()-start,"p1-p2 startet"); return result })
.then(() => { console.log(Date.now()-start,"p1-p2 done ") })
.then(() => {
p3 = test_p("C", 5)
.then((result) => { console.log(Date.now() - start, result); return result })
return p3;
});
然而,你的整体代码可以被极大地简化,并提高可读性,如下所示:
const start = Date.now();
async function delay(name, timeInSec) {
return new Promise((res) => setTimeout(res, timeInSec * 1000)).then(() =>
console.log(name, Date.now() - start)
);
}
console.log("start:", start);
const A = delay("A", 2);
const B = delay("B", 5);
const D = delay("D", 7);
const ABC = Promise.all([A, B]).then(() => delay("C", 5));
const CDE = Promise.all([ABC, D]).then(() => delay("E", 2));
<details>
<summary>英文:</summary>
The issue your current code is that the last `.then()` call in `pp1` doesn't return `p3`. As a result, you start timer C, but you never make it a dependency of `pp1`. So to fix it, simply return `p3` inside that `.then()`, like so:
```js
pp1 = Promise.all([p1, p2])
.then((result) => { console.log(Date.now()-start,"p1-p2 startet"); return result })
.then(() => { console.log(Date.now()-start,"p1-p2 done ") })
.then(() => {
p3 = test_p("C", 5)
.then((result) => { console.log(Date.now() - start, result); return result })
return p3;
});
However, your code overall can be immensely simplified and improved for readability like so:
const start = Date.now();
async function delay(name, timeInSec) {
return new Promise((res) => setTimeout(res, timeInSec * 1000)).then(() =>
console.log(name, Date.now() - start)
);
}
console.log("start:", start);
const A = delay("A", 2);
const B = delay("B", 5);
const D = delay("D", 7);
const ABC = Promise.all([A, B]).then(() => delay("C", 5));
const CDE = Promise.all([ABC, D]).then(() => delay("E", 2));
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论