Javascript - 处理异步竞争条件
Javascript - Handling asynchronous race condition
N.B。在删除重复之前:
我意识到类似的问题之前已经被问过很多次,但是我花了几个小时尝试使用其他人的回复来实现这个问题,最近一次是来自 noseratio 在这个线程 Proper way to wait for one function to finish before continuing? 中的回复,但没有成功。
我有一个 nodeJS 服务器,当我的函数 f1 请求它时,它成功地 returns 数据,另一个函数 f2 调用 f1,然后打算对这个异步函数的输出做一些事情。我正在尝试使用 async/await 语法和 f2 中的附加承诺来执行此操作,如下所示。
async function f1(){
try{
let response = await fetch('MY SERVER URL');
let data = await response.json();
return await data;
}
catch(e) {
alert(e);
}
};
function f2() {
var promise = f1();
promise.then(function(result) {
JSONdata = promise.markers;
console.log("JSON read into f2");
})
console.log(JSONdata);
然后 f2 继续做其他事情...
然而,问题是我遇到了竞争条件,结果是 f1 没有及时返回,无法用它做任何事情,所以变量是未定义的。
任何有关如何缓解此问题的帮助都将不胜感激,谢谢。
坚持这个模式。
async func1() {
console.log('this is async function')
return JSON.parse(await fetch(options))
}
func2 () {
console.log('this is not async function')
}
if(await func1()){
func2()
}
而且您在函数 1 中有太多等待。只等待 return 的承诺。
在这个级别上,您不应该将自己与混合 '.then' 和 'await' 语法混淆。尝试坚持一种模式,然后探索另一种模式。然后混合。
像这样的东西应该可以工作:
async function f1() {
try {
const response = await fetch('MY SERVER URL')
return await response.json()
} catch(e) {
console.error(e)
}
}
async function f2() {
const { markers } = await f1()
console.log(`Result supplied to 'f2': ${markers}`)
}
在您的代码中,return await data
中的 await
是多余的,因为 data
不是一个承诺;此外,f2
似乎不完整。
请注意,虽然一般来说,return await...
在 async
函数中是不必要的(并且被认为是错误的形式,即使它是无害的),如果你想要一个周围的 try...catch 到赶上承诺拒绝,那么 return await...
是必要的。参见 。
您应该将使用 f1
结果的逻辑移动到 then
回调中。
function f2() {
var promise = f1();
promise.then(function(result) {
var JSONdata = result.markers;
console.log("JSON read into f2");
console.log(JSONdata);
});
}
或将 f2
更改为 async function
so you can await
return 值。
async function f2() {
var result = await f1();
var JSONdata = result.markers;
console.log("JSON read into f2");
console.log(JSONdata);
}
如果你还没有,看看MDN Using Promises guide, which explains them pretty thorough. When you have an understanding of how promises work async
/await
也会变得更容易理解。
N.B。在删除重复之前: 我意识到类似的问题之前已经被问过很多次,但是我花了几个小时尝试使用其他人的回复来实现这个问题,最近一次是来自 noseratio 在这个线程 Proper way to wait for one function to finish before continuing? 中的回复,但没有成功。
我有一个 nodeJS 服务器,当我的函数 f1 请求它时,它成功地 returns 数据,另一个函数 f2 调用 f1,然后打算对这个异步函数的输出做一些事情。我正在尝试使用 async/await 语法和 f2 中的附加承诺来执行此操作,如下所示。
async function f1(){
try{
let response = await fetch('MY SERVER URL');
let data = await response.json();
return await data;
}
catch(e) {
alert(e);
}
};
function f2() {
var promise = f1();
promise.then(function(result) {
JSONdata = promise.markers;
console.log("JSON read into f2");
})
console.log(JSONdata);
然后 f2 继续做其他事情...
然而,问题是我遇到了竞争条件,结果是 f1 没有及时返回,无法用它做任何事情,所以变量是未定义的。
任何有关如何缓解此问题的帮助都将不胜感激,谢谢。
坚持这个模式。
async func1() {
console.log('this is async function')
return JSON.parse(await fetch(options))
}
func2 () {
console.log('this is not async function')
}
if(await func1()){
func2()
}
而且您在函数 1 中有太多等待。只等待 return 的承诺。 在这个级别上,您不应该将自己与混合 '.then' 和 'await' 语法混淆。尝试坚持一种模式,然后探索另一种模式。然后混合。
像这样的东西应该可以工作:
async function f1() {
try {
const response = await fetch('MY SERVER URL')
return await response.json()
} catch(e) {
console.error(e)
}
}
async function f2() {
const { markers } = await f1()
console.log(`Result supplied to 'f2': ${markers}`)
}
在您的代码中,return await data
中的 await
是多余的,因为 data
不是一个承诺;此外,f2
似乎不完整。
请注意,虽然一般来说,return await...
在 async
函数中是不必要的(并且被认为是错误的形式,即使它是无害的),如果你想要一个周围的 try...catch 到赶上承诺拒绝,那么 return await...
是必要的。参见
您应该将使用 f1
结果的逻辑移动到 then
回调中。
function f2() {
var promise = f1();
promise.then(function(result) {
var JSONdata = result.markers;
console.log("JSON read into f2");
console.log(JSONdata);
});
}
或将 f2
更改为 async function
so you can await
return 值。
async function f2() {
var result = await f1();
var JSONdata = result.markers;
console.log("JSON read into f2");
console.log(JSONdata);
}
如果你还没有,看看MDN Using Promises guide, which explains them pretty thorough. When you have an understanding of how promises work async
/await
也会变得更容易理解。