Promise 的执行顺序详解
在前端开发中,我们经常会用到 Promise 这个概念,它是一种用于异步编程的解决方案,用于解决回调地狱的问题。但是,如果对于 Promise 的执行顺序不理解,就可能会导致意想不到的错误。因此,在本文中,我们将详细讨论 Promise 的执行顺序。
Promise 的执行顺序
Promise 有三个状态:进行中(pending)、已完成(fulfilled)和已拒绝(rejected)。在开始讲述 Promise 的执行顺序之前,让我们先回忆一下 Promise 经典的执行流程:
-- -------------------- ---- ------- --- ------- - --- ----------------- ------- -- - -- ---- -- --------------------- -- -------------------- --- ------- ----------- -- - -- ----------- -- ------------ -- - -- ---- ---
当我们调用 new Promise
的时候,传入的参数应该是一个函数(executor),该函数接受两个参数:resolve
和 reject
。这个函数中,我们通常会进行一些异步操作,如果操作成功,就调用 resolve(value)
;如果操作失败,就调用 reject(error)
。Promise 被创建时一开始处于 pending 状态。
这时,我们调用 promise.then()
来注册异步操作成功后的回调。如果 promise 还处于 pending 状态,那么这个回调会在 promise 状态变为 fulfilled 的时候被调用,同时传递成功的结果 value。
如果在异步操作过程中出现了错误,就会调用 reject()
方法,使 promise 状态变为 rejected。这时,我们可以调用 promise.catch()
来处理这个错误。如果 promise 状态变为 rejected 并且没有被处理,那么就会抛出一个错误。
Promise 的解决方式
我们可以通过以下几种方式来解决 Promise 的执行顺序问题:
1. 使用 then() 方法
-- -------------------- ---- ------- --- ------- - --- ----------------- ------- -- - ----------------------- ---------- ---------- -- - -------------------- --- ------------------- -- ------------- -- --- -- ----
在这个例子中,Promise 对象被创建后,先输出 Promise
,然后执行 then()
中的代码,输出then
,最后输出 Hi!
。
Promise 状态一变为 resolved,就会按照注册 then()
的顺序依次执行。
2. 使用 async/await 方法
-- -------------------- ---- ------- ----- -------- ----- - --------------------- ----- ------ --------------------- - ----- -------- ----- - ----------------------- - ------ ------------------- -- ----------- -- ------- -- --- -- -----
在这个例子中,我们定义了两个函数 foo()
和 bar()
。foo()
是一个异步函数,其中包含了一个 await bar()
,当 foo()
执行到 await bar()
时,它会暂停执行,并等待 bar()
函数返回一个 Promise。当 Promise 状态变为 resolved 后,foo()
会继续执行后面的代码。
Promise 函数执行顺序的误区
在 Promise 函数执行的过程中,我们应该注意以下一些常见的误区:
1. Promise.doSomething().then(handleSuccess, handleError) 与 Promise.doSomething().catch(handleError)
-- -------------------- ---- ------- ----------------- -------- -- - ------ ------------------- -- ------------ -- - -------------------- ----- -------------- -- ------------ -- - --------------------------- --
以上代码输出结果为 1
,而不是 Oops
。这是因为在第三个操作时,我们抛出了一个错误。在这种情况下,后面的 catch
会捕获到这个错误,并且立即停止执行。因此,就不会输出错误信息了。
2. 多个 .catch()
如果一个 Promise 经历过多个 then()
回调,那么后面有多个 catch()
回调,它只会走一个。这是因为 catch()
回调只会捕获大上一个 then()
回调的错误信息。
-- -------------------- ---- ------- ----------------- -------- -- - ----- --- ----------- - --------- -- ------------ -- - --------------------------- ------ -------- -- ------------ -- - -------------------- -- ------------ -- - --------------------------- --
以上代码输出结果为 Step 1 failed
和 hello
。这是因为第一个 catch()
中返回了一个字符串 hello
,然后第二个 catch()
就不会处理错误信息。
结论
在日常开发中,我们经常使用 Promise 来进行异步编程。然而在使用 Promise 时,我们必须非常清楚 Promise 的执行顺序,以便确保代码的正确性。正确使用 Promise 不仅可以提高代码质量还可以提高效率。
在接下来的学习过程中,请牢记 Promise 的执行顺序,避免常见的误区。掌握 Promise 会大大提升你的代码质量和学习效率。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6717584ead1e889fe2211cea