Lah*_*ori 6 javascript ajax ecmascript-6 es6-promise arrow-functions
该线程详细解释了同步与异步之间的区别以及可能的解决方案,但我已经在使用其中一种解决方案,但仍然出现错误。我想我ES
在这里达到了我的理解极限,所以我真的需要关于这个问题的帮助,因为我只是不明白为什么它会丢失。下面是我在项目中使用的代码片段nuxt
,但它与它没有任何关系,因为我从后端移植了这个代码片段,即express
.
async fetch({store, error}) {
let series = '', courses = [], album = {}
store.state.courses.forEach(async course => {
album = {...course}
series = course.uri.split('/')[2]
try {
const {data: {data}} = await axios.get('http://localhost:3000/luvlyapi/videos', {
params: {
series //? album id
}
})
album['videos'] = data
courses.push(album)
console.log('loop', courses)
} catch (err) {
error({statusCode: err.statusCode, message: err})
}
})
console.log({courses})
store.commit('SET_COURSES', courses)
Run Code Online (Sandbox Code Playgroud)
您可以看到数组正在被推送,但循环结束后仍然为空。
.forEach()
不等待您的异步回调。它只是愉快地继续循环,您记录 的值courses
,然后一段时间后,await
回调内的所有操作完成,并将值放入courses
。因此,这是在将数据放入变量之前查看变量的时间问题。
值得理解的是,await
仅暂停本地函数执行(最近的函数范围),在您的情况下是回调.forEach()
。它不会导致更高级别的任何事情暂停。而且,由于.forEach()
甚至不查看回调返回的内容,因此它肯定不会查看回调返回的承诺async
。因此,一旦您按下await
,您的async
回调就会返回一个承诺。循环.forEach()
看到回调返回并立即启动循环的下一次迭代,即使您的await
内部回调尚未完成。
重要的是要理解,await
仅暂停本地函数,而不是其上方的任何内容,也不是任何调用者。当你的async
函数到达第一个时await
,该函数就会向外界返回一个承诺。为了让外部世界也停下来,它必须兑现承诺做一些事情,而事实.forEach()
并非如此。
for
另一方面,循环将实际函数保留在内部await
,因此整个作用域会随着await
. 如果您希望循环实际上用 暂停await
,那么请使用for
循环,而不是.forEach()
循环。
例如,您可以这样做:
async fetch({store, error}) {
let series = '', courses = [], album = {};
for (let course of store.state.courses) {
album = {...course}
series = course.uri.split('/')[2]
try {
const {data: {data}} = await axios.get('http://localhost:3000/luvlyapi/videos', {
params: {
series //? album id
}
})
album['videos'] = data
courses.push(album)
console.log('loop', courses)
} catch (err) {
error({
statusCode: err.statusCode,
message: err
})
}
}
console.log({courses})
store.commit('SET_COURSES', courses)
}
Run Code Online (Sandbox Code Playgroud)
仅供参考,您的原始实现还存在一个问题,即在同时运行的多个异步回调之间共享更高级别的作用域变量,这将导致一个回调践踏另一个回调。解决方案是要么按照我的代码示例显示并序列化异步调用,以便它们不会同时进行,要么将变量声明为异步范围的本地变量,以便每个异步回调都有自己的单独变量。
归档时间: |
|
查看次数: |
2017 次 |
最近记录: |