Promise.all中多个Promise的开始执行顺序的问题?

Demo

从日志输出来看 先执行了p1后执行p2,

问题

1.Promise.all的参数接受一个Promise数组, Promise数组中每一个Promise的执行函数的 开始执行顺序是怎样的?
是按照数组中的顺序 开始执行每一个Promise的执行函数吗?从实际日志输出来看 好像是数组的倒序
(注意问题问题的是Promise的执行函数的 开始执行顺序,并不是Promise的完成顺序,仅仅是执行函数的开始实行顺序)

  1. 实际Promise.all的场景中参数Promise数组中的每一个Promise之间应该是没有依赖性的吧?

我有一个场景: 做一个爬虫,点击登录按钮,页面发生跳转。我需要等待登录请求和页面跳转这两个事件的执行完成。
puppeteer API的写法如下

  const [response] = await Promise.all([
  page.waitForNavigation(waitOptions),
  page.click(selector, clickOptions),
]);

我对这个写法的疑问是: 正常情况下是 点击按钮先执行,然后才会发生页面的跳转,等待页面的跳转完成,也就是这两个Promise之间的执行函数有顺序要求, 这种写法合理吗?

b

阅读 1k
avatarAI BotBETA
  1. Promise.all的参数接受一个Promise数组, Promise数组中每一个Promise的执行函数的开始执行顺序是怎样的?

Promise.all 的参数确实是一个 Promise 对象的数组。当你在 Promise.all 中传入多个 Promise 对象时,这些 Promise 对象的执行函数的开始执行顺序并不是按照它们在数组中的顺序来的。实际上,这些 Promise 对象的执行函数是并行启动的,而不是串行启动。这意味着它们几乎会同时开始执行。

结论: Promise.all 中的 Promise 对象的执行函数是并行启动的,而不是按照数组中的顺序。

  1. 实际Promise.all的场景中参数Promise数组中的每一个Promise之间应该是没有依赖性的吧?

是的,当你在 Promise.all 中使用多个 Promise 对象时,这些 Promise 对象之间应该是没有依赖性的。Promise.all 的设计目的就是为了处理多个独立的异步操作,并且当所有操作都完成时返回结果。

结论: 在 Promise.all 的场景中,参数 Promise 数组中的每一个 Promise 之间应该是没有依赖性的。

  1. 关于你的爬虫场景的问题

在你的爬虫场景中,你使用 page.waitForNavigation()page.click() 在 Promise.all 中。这种写法是有问题的,因为这两个操作是有依赖性的:你需要在点击按钮后等待页面跳转完成。在这种情况下,你应该使用 Promise.all 的变种 Promise.allSettled,这样无论 Promise 是 resolve 还是 reject,都会等待它们完成。

正确的写法应该是:

const [response] = await Promise.allSettled([
  page.click(selector, clickOptions),
  page.waitForNavigation(waitOptions),
]);

这样,page.click() 会先执行,然后 page.waitForNavigation() 会等待页面跳转完成。无论哪个 Promise 先完成,response 都会包含相应的结果。

1 个回答
  1. promise 实例化之后立即开始执行,所以应该和实例化的顺序有关,和数组内顺序无关。如果是直接在数组里实例化,那就是数组正序。
  2. 你所说的用例里明显存在先后顺序,自然不能用 Promise.all,应该 await 两次。
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏