练习

跟踪手术刀

村里的乌鸦拥有一把老式的手术刀,他们偶尔会用于特殊的任务 - 比如说,切开纱门或包装。 为了能够快速追踪到手术刀,每次将手术刀移动到另一个鸟巢时,将一个条目添加到拥有它和拿走它的鸟巢的存储器中,名称为"scalpel",值为新的位置。

这意味着找到手术刀就是跟踪存储器条目的痕迹,直到你发现一个鸟巢指向它本身。

编写一个异步函数locateScalpel,它从它运行的鸟巢开始。 你可以使用之前定义的anyStorage函数,来访问任意鸟巢中的存储器。 手术刀已经移动了很长时间,你可能会认为每个鸟巢的数据存储器中都有一个"scalpel"条目。

接下来,再次写入相同的函数,而不使用asyncawait

在两个版本中,请求故障是否正确显示为拒绝? 如何实现?

  1. async function locateScalpel(nest) {
  2. // Your code here.
  3. }
  4. function locateScalpel2(nest) {
  5. // Your code here.
  6. }
  7. locateScalpel(bigOak).then(console.log);
  8. // → Butcher Shop

构建Promise.all

给定Promise的数组,Promise.all返回一个Promise,等待数组中的所有Promise完成。 然后它成功,产生结果值的数组。 如果数组中的一个Promise失败,这个Promise也失败,故障原因来自那个失败的Promise

自己实现一个名为Promise_all的常规函数。

请记住,在Promise成功或失败后,它不能再次成功或失败,并且解析它的函数的进一步调用将被忽略。 这可以简化你处理Promise的故障的方式。

  1. function Promise_all(promises) {
  2. return new Promise((resolve, reject) => {
  3. // Your code here.
  4. });
  5. }
  6. // Test code.
  7. Promise_all([]).then(array => {
  8. console.log("This should be []:", array);
  9. });
  10. function soon(val) {
  11. return new Promise(resolve => {
  12. setTimeout(() => resolve(val), Math.random() * 500);
  13. });
  14. }
  15. Promise_all([soon(1), soon(2), soon(3)]).then(array => {
  16. console.log("This should be [1, 2, 3]:", array);
  17. });
  18. Promise_all([soon(1), Promise.reject("X"), soon(3)])
  19. .then(array => {
  20. console.log("We should not get here");
  21. })
  22. .catch(error => {
  23. if (error != "X") {
  24. console.log("Unexpected failure:", error);
  25. }
  26. });