吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1087|回复: 4
收起左侧

[求助] 关于前端Ajax请求异步转同步的问题

[复制链接]
1452079621 发表于 2021-10-31 23:26
本人后端程序员,一般在公司工作时都是前后端一起写,在写前端请求代码的时候经常会遇到异步同步的问题

场景模拟:

文章中代码为即兴编写,例如单词拼错之类不影响阅读的小问题请忽略

假设在一段JS代码中涉及到请求,获取返回值后执行业务逻辑的代码,我们一般这么写:

test() {
    // 请求参数
    let parameter = {id: 123, name: "hahaha"}
    // http为封装好的请求代码
    http.postRequest("http://url.com", parameter).then(res => {
    // res为请求结果,根据结果处理一些数据...
    }).catch(err => {
        console.log("[ERROR]==>>", err);
    })
    // 其余代码...
}


众所周知,请求返回的结果是Promise对象,通过.then或者.cache来执行后续业务逻辑,而且Promise回调的代码是异步执行的,例如:

test() {
    // 返回结果
    let result = null;
    // 发起请求获取返回结果
    http.postRequest("url", {id: 123}).then(res => {
        result = res;
    }).catch(err => {
        console.log("[ERROR]==>>", err);
    })
    // 打印返回结果
    console.log("result", result);
}


这种情况下result打印的结果为null,因为请求是异步的,在请求结束调用回调之前下面的打印语句已经执行了,所以打印结果为null

但是有些情况异步请求是满足不了,所以接触到了async和awite关建字,可以讲Promise异步转同步,如下所示:

async test() {
    // 返回结果
    let result = null;
    // 发起请求获取返回结果
    let result = awite http.postRequest("url", {id: 123});
    // 打印返回结果
    console.log("result", result);
}


通过这种写法可以讲请求改为同步的方式,这样打印的result就不会为null了,但是这样就面临了一个新的问题,我写test这个方法肯定是要在别的地方调用的,例如:

initPage() {
    this.initData();
    this.test();
    this.flushPage();
}


上面这一段代码本来是按照顺序执行的,但是因为test方法被async修饰了,所以他也变成异步方法了,想要让initPage方法正常执行,就需要给他也要加上async/awite:

async initPage() {
    this.initData();
    awite this.test();
    this.flushPage();
}


这样一来initPage方法正常执行了,但是如果有别的地方调用initPage方法还是会掉进这个坑里


提出问题:

有没有什么办法在test方法中彻底完成异步转同步的功能,同时不影响initPage的代码?

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

bhbhxy 发表于 2021-11-1 08:40
ajax的底层是由xmlhttprequest实现的,在其open方法中可以提供多个参数,其中async参数可以控制是否为异步,所以可以考虑在封装方法中暴露这个参数,调用时传入它可以控制是异步或者同步请求。
--------------
async 可选
一个可选的布尔参数,表示是否异步执行操作,默认为true。如果值为false,send()方法直到收到答复前不会返回。如果true,已完成事务的通知可供事件监听器使用。如果multipart属性为true则这个必须为true,否则将引发异常。
主线程上的同步请求很容易破坏用户体验,应该避免;实际上,许多浏览器已完全弃用主线程上的同步XHR支持。在 Worker中允许同步请求
 楼主| 1452079621 发表于 2021-11-1 10:14
bhbhxy 发表于 2021-11-1 08:40
ajax的底层是由xmlhttprequest实现的,在其open方法中可以提供多个参数,其中async参数可以控制是否为异步 ...

拿我最近写的微信小程序来说,请求代码被封装为wx.request({}),我们根本接触不到XMLHttpRequest,想要异步转同步只能使用async/awite,这样该怎么办?
snake.state 发表于 2021-11-1 10:16
initPage() {
  async function run() {
    this.initData();
    await this.test();
    this.flushPage();
  }

  run();
}
hellostranger 发表于 2021-11-4 17:35
就举的这个栗子,实际上用到的时候都必须得是异步的
俺们前端封装http请求,大概都这样

await是关键字
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 23:00

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表