如何让AngularJS的$http实现类似jQuery $.ajax的同步请求直接返回响应数据
为什么async+await的写法仍然返回promise
按照ECMAScript标准规定,所有被async关键字修饰的函数,返回值必然是Promise对象:不管你函数内部return的是普通值还是其他类型,都会被自动包装为fulfilled状态的Promise。只有在另一个async函数内部用await调用该async函数时,才能拿到实际的返回值,你直接在非async上下文调用拿到的永远是Promise,这是语法层面的规则,和你的内部逻辑无关。
另外需要注意:AngularJS的$http服务本身就不支持同步请求配置,你传入的async: false参数会被$http内部直接忽略,它底层强制走异步逻辑,所以不管你怎么封装$http,都不可能拿到同步返回的响应数据。
可行的改造方案
如果坚持要实现同步请求、且完全不改动业务侧调用代码,只能放弃使用AngularJS的$http服务,直接基于原生XMLHttpRequest封装同步请求逻辑,替换Core.libs.prototype.send方法的内部实现即可,示例代码如下:
Core.libs.prototype.send = function(...) { // 从入参提取你的请求配置,和之前的options参数对齐即可 const options = { // 保留你原来的其他配置项,比如url、method、headers、data等 // ... }; const xhr = new XMLHttpRequest(); // 第三个参数传false代表开启同步模式 xhr.open(options.method || 'GET', options.url, false); // 注入请求头,和你之前$http的默认请求头保持一致即可 if (options.headers) { Object.keys(options.headers).forEach(headerKey => { xhr.setRequestHeader(headerKey, options.headers[headerKey]); }); } // 发送请求,同步模式下会阻塞主线程直到请求响应完成 xhr.send(options.data ? JSON.stringify(options.data) : null); // 处理响应结果,和你之前的返回逻辑对齐 if (xhr.status >= 200 && xhr.status < 300) { return JSON.parse(xhr.responseText); } else { return new Error(xhr.statusText); } }
注意:同步请求会完全阻塞浏览器主线程,请求完成前用户界面会完全卡死无响应,仅建议特殊场景下临时兼容老业务使用,长期来看还是建议逐步改造业务代码适配异步Promise调用模式。
内容的提问来源于stack exchange,提问作者nordictelecom
相关产品推荐
相关产品推荐

