引言
随着前端技术的不断进步,Promise 已经成为了异步编程的主流方式之一。而 Promise 的链式调用方式可以让我们更加方便地处理异步任务,同时也有些地方需要我们格外注意,因为 Promise 链式调用时会有一些有趣的异常场景。本文将围绕这些场景展开探究,以期为大家提供参考并尽可能详尽地解答各位的疑惑。
Promise 链式调用基础知识
在开始探究之前,我们先来复习一下 Promise 链式调用的基础知识。
Promise 链式调用就是将多个 Promise 实例串联起来,通过 then 方法传递数据、错误等信息,并继续返回一个 Promise 实例。例如:
-- -------------------- ---- ------- --- ----------------- ------- -- - ------------------ -- ----------- -- - ----------------- -- --- -------- ------ ---------- -- ----------- -- - ----------------- -- --- --------- ---
上面的代码中,第一个 then 方法的回调函数返回了一个字符串 "success",而第二个 then 方法的回调函数则用这个返回值来进行处理。可以看到,当 Promise 实例的状态变为 resolved 并执行完后,就会调用 then 方法中的回调函数。
需要注意的是,如果前一个 Promise 实例中出现了错误,就会跳过后续的 then 方法直接执行 catch 方法的回调函数或抛出异常,例如:
-- -------------------- ---- ------- --- ----------------- ------- -- - ---------- ------------ ------------- -- ----------- -- - -- ---- ----------------- -- ---------- -- - ----------------------- -- --- ------ ---------- ---
上面的代码中,Promise 实例返回的是一个 rejected 状态,因此直接执行了 catch 方法的回调函数,输出了错误信息。
Promise 链式调用的异常场景
忘记返回 Promise 实例
在 Promise 链式调用过程中,前一个 Promise 实例返回的状态决定了后续代码的执行顺序,我们需要保证在 then 方法中返回一个 Promise 实例,否则就会出现代码执行顺序不符合预期的问题。
例如,下面的示例中就是没有返回 Promise 实例时的情况:
-- -------------------- ---- ------- --- ----------------- ------- -- - ------------------ -- ----------- -- - -- --- ------- ---------- ------- -- --- ----------------- ------- -- - ------------------- --- -- ----------- -- - ----------------- -- ---- ---
上面的代码中,第二个 then 方法并没有得到真正的 Promise 实例,因此不会执行其回调函数。
正确的方式是返回一个 Promise 实例,例如:
-- -------------------- ---- ------- --- ----------------- ------- -- - ------------------ -- ----------- -- - -- --- ------- --------- ------- -- ------ --- ----------------- ------- -- - ------------------- --- -- ----------- -- - ----------------- -- --- --------- ---
在 Promise 链式调用中抛出异常
在 Promise 链式调用中,如果在 then 方法中抛出异常,就会跳过后续 then 方法直接执行 catch 方法的回调函数或抛出异常。下面的代码就是抛出异常时的场景:
-- -------------------- ---- ------- --- ----------------- ------- -- - ------------------ -- ----------- -- - ----- --- ------------ ------------ -- ----------- -- - -- ---- ----------------- -- ---------- -- - ----------------------- -- --- ------ ---------- ---
上面的代码中,第一个 then 方法抛出了异常,因此直接执行了 catch 方法的回调函数,输出了错误信息。
在异步代码中处理异常
在异步代码中抛出异常时,因为异步的原因我们很难立即得知异常情况,因此我们经常会使用 try...catch 语句块来处理异常。
但是在使用 Promise 链式调用时,因为 then 方法中的代码会异步执行,try...catch 语句块无法捕获到其中的异常。
例如,下面的代码中使用 try...catch 语句块尝试捕获 then 方法中的异常:
-- -------------------- ---- ------- --- ----------------- ------- -- - ------------------ -- ----------- -- - ------------- -- - ----- --- ------------ ------------ -- ------ -- ----------- -- - -- ---- ----------------- -- ---------- -- - ----------------------- -- ---- --- --- - -- ------ ------------------------- -- - ----- --- ------------ ------------ --- - ----- --- - ----------------------- -- ---- -
上面的代码中,虽然我们在 then 方法中抛出了异常,但是 try...catch 语句块无法捕获到此异常,因为 Promise 的执行是异步的。
正确的方式是在 then 方法中处理异常:
-- -------------------- ---- ------- --- ----------------- ------- -- - ------------------ -- ----------- -- - -- --------- ------ --- ----------------- ------- -- - ------------- -- - --- - ----- --- ------------ ------------ - ----- --- - ---------- - -- ------ --- -- ----------- -- - -- ---- ----------------- -- ---------- -- - ----------------------- -- --- ------ ---------- ---
上面的代码中,我们在异步代码中通过 try...catch 语句块捕获了异常,并将异常信息 reject 出去进行下一步处理。
总结
通过本文的探究,我们发现 Promise 链式调用时确实存在一些异常场景需要我们格外注意。如果不遵循 Promise 链式调用的规则,就会导致代码执行顺序出现问题或者异常无法被捕获。
因此,在使用 Promise 链式调用时,我们需要遵循 Promise 链式调用的规则,以及注意异常场景的处理方式,让我们的代码更加健壮。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/647f77eb48841e9894f1adb8