NodeJS Express API调用结构异步事件



我正在NodeJS和Express中做一个业余项目,但我被异步调用淹没了。我遇到了一个bug,我想与社区一起反弹。

我目前使用Express进行此布局,我正在向其发送投递请求。

Express(后端(

app.post("/", async (req, res) => {
const createDocument = (args1) => {
// declare some variables ...
// for loop ...
// (quite fast)
loadFile(args2, async () => {
// upload a file (quite slow)
await upload(file, filePath)
//send post request to third party (quite fast)
let res = await axios.post(url, data, {
headers: {
'X-Auth-Token': KEY
}
}).then(res => console.log('success')).catch(error => console.log('failure'))
})
}
const args1 = "someargs"
await new Promise(resolve => setTimeout(resolve, 2000))
await createDocument(args1)
res.end()
})

React(前端(

const saveDocButtonClicked = useCallback(async (event) => {
// do some stuff ...
await axios.post('/', {
headers: {
'Content-Type': 'application/json'
},
jsonData
}).then(res => console.log('Data sent')).catch(err => console.log(err.data))
// do some other stuff ...
}

我希望React应用程序等待,在从API调用获得对Express后端的正确响应之前不要继续。

我希望Express应用程序只有在执行完所有任务后才能做出正确的响应

到目前为止,对于较小的文件,这种方法效果良好,但随着文件大小的增加,它们不再保存/存储在数据库中。

我注意到的关键区别是,在这些糟糕的情况下,字符串successfailure应该来自Express后端的这段代码;CCD_ 3不再被输出。因此,在某个地方,异步事件可能会突然发生。

我确信我犯了很多错误,请随时指出,我很想学习这一点,我是一个异步呼叫的大一新生。

从createDocument返回promise将允许await createDocument(args1)等待,直到它完成执行

app.post("/", async (req, res) => {
const createDocument = (args1) => {
return new Promise((resolve,reject)=>{
// declare some variables ...
// for loop ...
// (quite fast)
loadFile(args2, async () => {
// upload a file (quite slow)
await upload(file, filePath)
//send post request to third party (quite fast)
let res = await axios.post(url, data, {
headers: {
'X-Auth-Token': KEY
}
}).then(res => console.log('success')).catch(error => console.log('failure'))
resolve(res);
//TODO:: Reject if some error occurs;
})
});
}
const args1 = "someargs"
await new Promise(resolve => setTimeout(resolve, 2000))
await createDocument(args1)
res.end()
})

对于这种事情,使用async await和then/catch是不好的方法。等待你可以做的工作

try {
const response = await axios.post('/', {
headers: {
'Content-Type': 'application/json'
},
jsonData
})
// Here is your data after response completed
const data  = response.json()
} catch(err) {
console.log(err)
} 

或者,您可以删除async/await并简单地使用then/catch

您的代码在语法上似乎是正确的(尽管遵循一些异步/等待最佳实践会更好,但这些不应该影响应用程序的逻辑(。你能提供一些样本输入、输出和预期输出吗?这样我就能更好地理解这个问题了?

同时,我认为它可能只是upload()的功能很慢,尤其是对于较大的文件,所以你只需要等待更多的时间就可以了;成功;或";失败";已记录

编辑:我在回调流中发现了一些不符合async/await流的内容。看起来createDocument没有等待,或者知道要等待loadFile完成,因为loadFile的东西是"隐藏的";在回调之后。所以我修改了createDocument以返回Promise:

app.post("/", async (req, res) => {
const createDocument = (args1) => {
// Return a promise that waits for loadFile
return new Promise((resolve, reject) => {
// declare some variables ...
// for loop ...
// (quite fast)
loadFile(args, () => {
// I dont like using async with callback, so I'mma use .then()
function makeAxiosRequest() {
return axios.post(url, data, {
headers: {
"X-Auth-Token": KEY,
},
});
}
// Only resolve createDocument after loadFile's stuff is finished
upload(file, filePath)
.then(() => makeAxiosRequest())
.then(() => console.log("Success"))
.catch((err) => console.log("Failure"))
.finally(resolve());
});
});
};
const args1 = "someargs";
await new Promise((resolve) => setTimeout(resolve, 2000));
await createDocument(args1);
// I like sending something to frontend for better debug experience
return res.json({ message: "Respond now ends" });
});

最新更新