我想先说一下,我查看了很多关于这个主题的stackoverflow问题,但我没有发现任何 "重复 "本身,因为它们都不包含可以解决这个特定情况的解决方案。
我主要看了 我如何从异步调用中返回响应?在异步函数中,"使用asyncawait的承诺 "这一节可以在异步函数中使用,但我正在研究的函数不是async,而且是现有代码库的一部分,我不能轻易改变。我无法将函数改为异步。
关于回调的部分也不行,这在下面会进一步解释。总之,我先说说我的问题。
我在JavaScript中编辑一个函数(标准函数,不是异步),添加一个异步函数调用。我想等到异步调用完成后再从函数中返回(因为异步调用的结果需要包含在返回值中)。我如何做到这一点?
我研究了使用回调,这将使我能够写出保证只在异步调用完成后运行的代码。然而,这不会中断原函数中的程序流,原函数仍然可以在回调运行之前返回。回调可以让我在异步函数之后依次执行一些东西,但它不允许我在最高层等待异步调用完成。
示例代码,不会返回想要的结果。
function getPlayers() {
... other code ...
let outfieldPlayers = asyncGetOutfieldPlayersCall()
... other code ...
allPlayers.add(outfieldPlayers)
return allPlayers // the returned value may or may not include outfield players
}
我面临的实际问题更复杂一些 我在for循环的每一次迭代中都要调用异步函数 需要等待所有调用完成后再返回 但是,我想如果我能解决这个比较简单的问题,我就能解决for循环的问题。
遗憾的是,以同步的方式等待异步代码是几乎不可能的。这是因为JS中没有线程(大多数JS运行时,但 一些 是). 所以代码要么是同步的,要么是异步的。
异步代码之所以能够实现,是因为有了 事件循环. 事件循环是javascript的一部分 运行时. 它的工作原理是保持一个回调函数的栈,当 活动 触发它们--通常是超时事件(你可以用 setTimeout()
)或IO事件(当你发出磁盘或HTTP请求时,或在用户交互时发生)。然而,这些回调只在 当没有其他代码运行时因此,只有当程序处于空闲状态时,且 都 函数已经返回。
这意味着像 "自旋循环 "这样的技术在线程环境中是行不通的,因为在自旋循环完成之前,异步代码不会运行。
更多信息。https:/medium.comfront-end-weeklyjavascript-event-loop-explained-4cd26af121d4。