如果一个 async Vuex action 是 运行 两次,那么 await 调用之后的代码可以是 运行 随机顺序吗?
If an async Vuex action is run twice, can the code following the await call be run in random order?
const actions = {
search: debounce(
async ({ commit, dispatch, getters, rootGetters }, { page = 1 }) => {
commit("setLoading", true);
commit("setPage", page);
console.log("Starting...")
const randId = Math.random() * 100;
console.log(randId);
const results = await EventApi.get();
console.log("Done: ", randId, `|${results.meta.slept}|`)
// After `await`
commit(page == 1 ? "setEvents" : "addEvents", results.events);
// ... and a bunch more commits after that.
}, 300, { leading: true, trailing: true })
}
}
如果上面的动作被调用两次:
store.dispatch('search', { page: 1 });
store.dispatch('search', { page: 1 });
假设第一个调用的请求需要10s完成,第二个调用的请求只需要1秒。
在第二次调用中await EventApi.get()
之后的代码是否在第一次调用之后执行call,甚至认为请求应该早点完成?我不会这么认为,但我的实验表明情况确实如此,所以我的代码一定有问题。
这是 Vuex 日志 + 我的一些评论:
https://gist.github.com/niuage/9e2dcd509dc6d5246b3a16af56ccb3d3
如果有帮助,这里是简化的 EventApi 模块:
const get = async () => {
const q = await fetch(someUrl);
const result = await q.json();
return result;
}
export default {
get
}
我问是因为我遇到了一个问题,我的结果计数与实际显示的结果不同步,这种情况极少发生,所以我猜这可能是因为两者之间存在竞争条件多个请求。
您示例中的第二个较短的调用将首先完成。这是因为 await
仅在 async
函数的上下文中等待。
由于 async/await
是一种不同的编写承诺的方式,您可以将其视为 return 一个承诺的 2 个单独的函数调用。一个不会耽误另一个
这是一个演示:
const delay = time => new Promise(resolve => setTimeout(() => resolve(), time))
async function wait(id, time) {
await delay(time);
console.log(id + ' complete.');
}
console.log('Starting 1...');
wait('#1', 5000);
console.log('Starting 2...');
wait('#2', 1000);
View the bottom portion of the demo for the console results.
上面的演示中的 async
函数是用 .then
编写的:
function wait(id, time) {
return delay(time).then(() => {
console.log(id + ' complete.');
});
}
如果您想强制示例中的第二个函数调用等待第一个函数调用,请将两个函数的调用上下文设为 async
函数,例如:
async created() {
// Assuming the `search` action returns its http promise!
await this.$store.dispatch('search', { page: 1 });
await this.$store.dispatch('search', { page: 1 });
...
}
const actions = {
search: debounce(
async ({ commit, dispatch, getters, rootGetters }, { page = 1 }) => {
commit("setLoading", true);
commit("setPage", page);
console.log("Starting...")
const randId = Math.random() * 100;
console.log(randId);
const results = await EventApi.get();
console.log("Done: ", randId, `|${results.meta.slept}|`)
// After `await`
commit(page == 1 ? "setEvents" : "addEvents", results.events);
// ... and a bunch more commits after that.
}, 300, { leading: true, trailing: true })
}
}
如果上面的动作被调用两次:
store.dispatch('search', { page: 1 });
store.dispatch('search', { page: 1 });
假设第一个调用的请求需要10s完成,第二个调用的请求只需要1秒。
在第二次调用中await EventApi.get()
之后的代码是否在第一次调用之后执行call,甚至认为请求应该早点完成?我不会这么认为,但我的实验表明情况确实如此,所以我的代码一定有问题。
这是 Vuex 日志 + 我的一些评论:
https://gist.github.com/niuage/9e2dcd509dc6d5246b3a16af56ccb3d3
如果有帮助,这里是简化的 EventApi 模块:
const get = async () => {
const q = await fetch(someUrl);
const result = await q.json();
return result;
}
export default {
get
}
我问是因为我遇到了一个问题,我的结果计数与实际显示的结果不同步,这种情况极少发生,所以我猜这可能是因为两者之间存在竞争条件多个请求。
您示例中的第二个较短的调用将首先完成。这是因为 await
仅在 async
函数的上下文中等待。
由于 async/await
是一种不同的编写承诺的方式,您可以将其视为 return 一个承诺的 2 个单独的函数调用。一个不会耽误另一个
这是一个演示:
const delay = time => new Promise(resolve => setTimeout(() => resolve(), time))
async function wait(id, time) {
await delay(time);
console.log(id + ' complete.');
}
console.log('Starting 1...');
wait('#1', 5000);
console.log('Starting 2...');
wait('#2', 1000);
View the bottom portion of the demo for the console results.
上面的演示中的 async
函数是用 .then
编写的:
function wait(id, time) {
return delay(time).then(() => {
console.log(id + ' complete.');
});
}
如果您想强制示例中的第二个函数调用等待第一个函数调用,请将两个函数的调用上下文设为 async
函数,例如:
async created() {
// Assuming the `search` action returns its http promise!
await this.$store.dispatch('search', { page: 1 });
await this.$store.dispatch('search', { page: 1 });
...
}