从异步讲到回调函数
在讲接下来的要点之前,我们必须理解两个名词:同步和异步。
所谓同步,指的是协同步调。既然叫协同,所以至少要有2个以上的事物存在。协同的结果就是:多个事物不能同时进行,必须一个一个的来,上一个事物结束后,下一个事物才开始。比如,先更新代码,然后再编译,接着再打包。这些操作由于后一步要使用上一步的结果,所以只能按照这种顺序一个一个的执行。这就是同步。
所谓异步,就是步调各异。既然是各异,那就是都不相同。所以结果就是:多个事物可以你进行你的、我进行我的,谁都不用管谁,所有的事物都在同时进行中。
一言以蔽之,同步就是多个事物不能同时开工,异步就是多个事物可以同时开工。
🆗,当理解好了这两个名词之后,我们就可以继续往下看了。
接下来我们讲讲回调。
回调的本质就是“将一个函数作为参数传递给另一个函数,并在适当的时间调用这个函数。它通过函数间的调用关系来实现解耦”。
比如现在有一个方法A和B,这两个方法没有任何的联系。当你使用回调,即B(A)的时候,就可以使得这两个方法有联系,还可以在异步的场景下确保方法的执行顺序。同时,B还可以决定什么时候调用A,以及A的执行结果如何影响B的后续逻辑。
我们以一个例子来体会一下,这是发生在我工作中的真实场景。我现在想调用后端的getGoodsById,然后通过getGoodsById的返回结果来更新newData的内容。我一开始是这样写的:
这样的写法是错误的,因为类似于调用后端接口的代码都不是这样子写的,我看了一下网上,正确的写法应该是这样的:
这样子就可以正确的调用接口获取数据了。但是这样问题出来了,大家有没有想过这个方法的执行过程是什么样的?在 getGoodsById
调用后,return newData
会立即执行,而 getGoodsById
的异步操作还未完成。这会导致返回的数据 newData
并未包含从接口返回的更新内容。这就是我们一直说的异步问题。
那我们有什么思路解决异步问题呢?可以将 return
的逻辑放在异步操作完成后执行就好了。卧槽,那不就是回调函数吗?所以我们的思路就是通过给 subTableChange
添加一个回调参数 callback
,在异步操作完成后调用这个回调函数,并将更新后的 newData
作为参数传递给它。
当调用
subTableChange
时,需要传入一个回调函数来处理更新后的数据。回调函数是这样的:
subTableChange
方法的思路是:如果 item.key
不是 "materialId"
,直接调用回调函数 callback
,将 newData
返回。如果 item.key
是 "materialId"
,调用接口 getGoodsById
。当接口返回数据后,更新 newData
。调用回调函数 callback
,将更新后的 newData
返回。