背景
JavaScript 作为一门动态语言,函数式编程在其中占据了非常重要的地位。随着前端应用越来越复杂,异步编程已经成为了必修课程。而 JavaScript 中的异步编程,除了传统的回调函数(Callback)和事件监听(Event Listener)之外,还可以利用 Promise 和 Generator 实现。
本文介绍了 ES6 Promise 结合 Generator 实现异步控制的方法,并提供了示例代码和解释。
Promise 基础知识
Promise 是一种异步编程模型,可以规避回调函数嵌套带来的深度嵌套问题,增强程序的可读性和可维护性。
Promise 有三种状态:pending、fulfilled 和 rejected。其中 pending 表示 Promise 对象的初始化状态,fulfilled 表示 Promise 对象的异步操作成功完成,rejected 表示 Promise 对象的异步操作失败。终态(即 fulfilled 或 rejected)不可逆转。
-- -------------------- ---- ------- ----- ------- - --- ----------------- ------- -- - ----- ------- - ---- -- ---------- -- --------- - ------------------ - ---- - ----------------- - -- ------- ------------- -- - ------------------ -- -- --------- -- --------------- -- - --------------------- -- -- --------- --
上述代码中,Promise 对象传入了一个回调函数,该回调函数具有 resolve 和 reject 两个参数。当异步操作成功完成时,调用 resolve 函数来返回成功信息;当异步操作失败时,调用 reject 函数来返回失败信息。
在后面的代码中,then 方法可以用来处理成功的回调函数,catch 方法可以用来处理失败的回调函数。
Generator 基础知识
Generator 是 JavaScript 中一种异步编程模型,通过函数的暂停和恢复机制,可以实现非阻塞的异步控制。
Generator 函数的关键字是 function*,它可以用 yield 关键字实现暂停和恢复。当函数执行到 yield 时,函数会被暂停,直到下一次被恢复执行。可以通过 next 方法来实现函数的恢复,next 方法返回一个对象,这个对象包含 done 和 value 两个属性。
-- -------------------- ---- ------- --------- ---------------- - ----- ------- ----- ------- ------ ------ - ----- -- - ---------------- ---------------------------- -- ------- ---------------------------- -- ------- ---------------------------- -- ------ ---------------------- -- ------ ----- ------ ----------
上面的代码中,helloGenerator 函数定义了一次遍历的过程,每次遍历 yield 一个字符串。函数遍历结束的时候,返回字符串 Done,并将 done 设为 true。
调用 helloGenerator 函数会返回一个 Generator 对象 hg,该对象可以通过 next 方法执行遍历过程。每次调用 next 方法,Generator 对象会搜索函数中的下一个 yield 表达式,并在表达式返回值的基础上暂停执行,等待下一次调用 next 方法。遍历结束后,Generator 对象的 done 属性被设置为 true,value 属性的值为遍历函数中的返回值。
Promise 结合 Generator 实现异步控制
Promise 和 Generator 的结合,可以用来实现非常灵活的异步控制,称为 Generator 函数的自动执行。
这种方式的基本思路是,编写一个异步任务函数,函数内部执行异步操作并返回 Promise 对象。当 Promise 对象 resolve 时,利用 Generator 函数的 next 方法执行下一个异步操作。当所有异步操作完成后,执行任务回调。
-- -------------------- ---- ------- --------- ----------- - ----- ------- - ----- ------------ ----- ------- - ----- ------------ ----- ------- - ----- ------------ ------ ------- - ------- - ------- - -------- ------------ - ------ --- ----------------- -- - ------------- -- - ---------- -- ----- -- - -------- ------------ - ------ --- ----------------- -- - ------------- -- - ---------- -- ----- -- - -------- ------------ - ------ --- ----------------- -- - ------------- -- - ---------- -- ----- -- - -------- -------------- - ----- --- - ------ ----- ---- - ------- -- - ----- ------ - --------------- -- ------------- - ------------------------- - ---- - ----------------------- - - ------ - -------------------
上面的示例代码中,asyncFunc 函数内部调用了三个异步任务函数 asyncTask1、asyncTask2 和 asyncTask3,将这三个异步任务函数作为 yield 表达式执行。由此,Generator 对象 hg 的执行过程如下图所示:
最后,调用 runAsync 函数并将 asyncFunc 函数作为参数传入,可以启动异步任务的执行过程。
总结和指导意义
JavaScript 中的异步编程已经成为了不可避免的问题。回调函数和事件监听虽然可以解决异步调用的问题,但是深度嵌套的问题依然存在且难以处理。
Promise 和 Generator 结合一起,在一定程度上解决了回调地狱的问题。通过将异步操作包装为 Promise 对象,并将该对象作为 yield 表达式传入 Generator 函数,可以实现更加灵活和可读性更高的异步编程。
这种编程模式的应用场景非常适用于前端框架中异步任务的处理,并且被各大框架广泛地应用。理解 Promise 和 Generator 的基本用法,以及如何将它们结合起来使用,是每一个前端工程师都必须掌握的技能。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/654dd04a7d4982a6eb731c58