请教一下各位大佬,js的async/await不起作用!

各位大佬,我最近在写一个读取ftp文件目录的项目,页头需要获取ftp的状态和文件数量等等信息,现在后端都已做好返回数据,但是前端遇到一个问题,就是我有两个axios异步请求函数,其中一个是获取ftp状态,另一个函数是获取ftp文件数量,而获取ftp文件数量的函数设置了延时报错机制,即超过了固定时间就超时报错(以免文件数过大递归造成内存溢出),但现在遇到的问题是:
如果让获取状态的函数和获取文件数量的函数同步执行的话,那么一旦刷新页面(尤其是清空浏览器缓存)将会造成获取状态的函数陷入阻塞状态(即一直读不到数据,经控制台查看网络请求为空白页)这样一个BUG,BUG截图下附;
于是我突发奇想需要改变机制为刷新进入页面时(即生命周期函数created()中)首先读取ftp状态,然后等待执行完成之后再执行读取ftp文件数量的函数,然后我就想到了promise里的async/await函数来尝试解决,但是依然遇到问题,await函数无法取得获取状态函数的返回信息,经控制台查看为underfind,也无法等待该函数执行完成在执行读取文件数量的函数;
文字描述不大好理解,我以下会贴上代码和截图以作例证:
1.初次加载页面正常状态(FTP文件数量和图片数量正在读取中)
请教一下各位大佬,js的async/await不起作用!
2.过了超时时间以后的状态(FTP文件数量和图片数量变为无法读取)
请教一下各位大佬,js的async/await不起作用!
3.清空缓存强制从服务器刷新(CTRL+F5)以后的状态(FTP状态也已经读取不到了,必须要通过重启php服务才能正常显示)(控制台所有请求返回全部是空白页,就不截图了)
请教一下各位大佬,js的async/await不起作用!
以下是代码片段:
1.读取ftp状态的异步请求函数:

handleLogin() {

axios.all([

axios.get('/api/handle_login.php'), //获取登录信息

axios.get('/api/ftp_connect.php'), //获取连接信息

])

.then(axios.spread((prev, next) => {

if (prev.data === "failed" || next.data === "failed") {

window.location.replace('/login.html')

ElementPlus.ElMessage({

type: 'info',

message: '您已登出',

})

} else {

// console.log(prev.data);

this.list.uname = prev.data.uname;

this.list.ftpUrl = prev.data.url_body;

this.list.ftpPort = prev.data.url_port === null ? "默认" : prev.data.url_port;

}

if (next.data === "success") {

this.list.conState = "已连接"

this.conStyle = "green"

} else {

this.list.conState = "连接失败"

this.conStyle = "red"

}

// console.log(prev.data, next.data)

}))

.catch(error => {

console.log(error);

});

},

2.读取ftp文件数量的异步请求函数(采用的async/await模式):

async getFileNum() {

let res = await this.handleLogin();

console.log(res) //这里是underfind返回值

//获取文件,图片数量(一旦执行将会造成阻塞)

axios.get('/api/ftp_getFileNum.php', { timeout: 1000 })

.then(response => {

let val = json.parse(response.data)

if (val.msg == "success") {

this.list.ftpFileNum = val.fileNum;

this.list.ftpImgNum = val.imgNum;

} else {

this.list.ftpFileNum = "无法读取";

this.list.ftpImgNum = "无法读取";

this.readStyle = "red"

}

})

.catch(error => {

console.log(error);

this.list.ftpFileNum = "无法读取";

this.list.ftpImgNum = "无法读取";

this.readStyle = "red"

});

},

3.create生命周期函数中的引用代码:

this.handleLogin()

this.getFileNum()

麻烦各位大佬指点迷津,谢谢!


回答:

先查个文档,发现

Concurrency (Deprecated)

Please use Promise.all to replace the below functions.

Helper functions for dealing with concurrent requests.

axios.all(iterable) axios.spread(callback)

当然这不是重点,重点是 await 在等啥?

await this.handleLogin() 从语义上讲是在等 handleLogin() 完成,但实际上 handleLoing() 没有返回任何东西,也就是说,返回了 undefined,那么 await undefined 当然是没有效果的。

一方面,await 需要等一个 Promise 对象,然后它会等到这个 Promise 有结果(resovled 或者 rejected)。另一方面,需要等的并不是 handleLogin(),而是其内部的 axios.all()

所以如果单纯的只是要解决等待的问题,可以稍稍修改一个 handleLogin()

handleLogin() {

return axios.all(....);

}

不过因为没有查到 axios.all() 的文档,只是根据 axios 的一惯行为,认为它是返回的 Promise。如果不是,那就要自己封装 Promise,小概率,不深入了。

建议阅读:理解 JavaScript 的 async/await


我用 await 改写了一下,但是没去分析逻辑,你自己看看逻辑对不对呵。

async handleLogin() {

// 改用 await 来写

// 用 Promise.all 代替 axios.all

const [prev, next] = await Promise.all([

axios.get("/api/handle_login.php"), //获取登录信息

axios.get("/api/ftp_connect.php"), //获取连接信息

]).catch(err => {

// 处理产生异常的情况,为了不写 try...catch

console.log(err);

// 但是要返回个数组,不然外面的 const [prev, next] = 解构会报错

return [];

});

// 如果是空的说明是出现了异常的情况(对空数组解构的结果)

if (!prev && !next) { return; }

if (prev.data === "failed" || next.data === "failed") {

// 这里进行了页面跳转,后面的 Message 应该会显示不出来,改在 onClose 事件中去跳转

// window.location.replace("/login.html");

ElementPlus.ElMessage({

type: "info",

message: "您已登出",

onClose: () => window.location.replace("/login.html")

});

} else {

// console.log(prev.data);

this.list.uname = prev.data.uname;

this.list.ftpUrl = prev.data.url_body;

this.list.ftpPort = prev.data.url_port === null ? "默认" : prev.data.url_port;

}

if (next.data === "success") {

this.list.conState = "已连接";

this.conStyle = "green";

} else {

this.list.conState = "连接失败";

this.conStyle = "red";

}

},

async getFileNum() {

let res = await this.handleLogin();

console.log(res); // 这里返回 undefined 是正常的,因为 handleLogin 并没有返回什么值

const response = await axios.get("/api/ftp_getFileNum.php", { timeout: 1000 })

.catch(error => {

console.log(error);

this.list.ftpFileNum = "无法读取";

this.list.ftpImgNum = "无法读取";

this.readStyle = "red";

});

if (!response) { return; } // catch 里没有返回值,所以如果进入了 catch,response 会是 undefined

// 原来写的 json.parse……确实定义了小写的 json?

// 如果没定义这里应该会报错,进入到 catch 中

let val = JSON.parse(response.data);

if (val.msg == "success") {

this.list.ftpFileNum = val.fileNum;

this.list.ftpImgNum = val.imgNum;

} else {

this.list.ftpFileNum = "无法读取";

this.list.ftpImgNum = "无法读取";

this.readStyle = "red";

}

console.log("END of getFileNum"); // 加个日志看是不是死在里面了

},


回答:

handleLogin() {

axios.all([

这里需要 return 出去,不然 await 不会等待。

handleLogin 为什么会调用两次?network 排查一下有没有异常。


回答:

handleLogin没有返回值请教一下各位大佬,js的async/await不起作用!


回答:

不用async/await,有方法做到吗?
用传统的callback啊

以上是 请教一下各位大佬,js的async/await不起作用! 的全部内容, 来源链接: utcz.com/p/937331.html

回到顶部