JS axios async/await 好像只能返回 promise

2022-07-27 19:57:53 +08:00
 luffy
async function hello() {
  return await Axios.request(options)
}

有办法返回最终值嘛? 而不是返回一个 promise

如果是在服务端,比如 nodejs 里面,如果想要返回一个 axios request 后的值给客户端

一般怎么处理的?

3610 次点击
所在节点    程序员
30 条回复
zhuangzhuang1988
2022-07-27 19:59:58 +08:00
没有办法。
xiangyuecn
2022-07-27 20:03:18 +08:00
这娃没救了,不知道加 async
AyaseEri
2022-07-27 20:08:09 +08:00
调用函数里也 await 不就行了
pagxir
2022-07-27 20:18:47 +08:00
这是异步调用。你是没有办法在单线程的 nodejs 直接转成同步调用的。要么多线程,要么去 hack 到 nodejs ,要么就只能继续异步调用。当然了,你可以换其他同步调用的实现
pendulum
2022-07-27 20:32:52 +08:00
async 函数只能返回 promise
elfive
2022-07-27 20:32:58 +08:00
async 修饰你调用这个函数的函数,同时调用语句前面加 await 关键字
或者调用的地方用.then 也行呀……
eason1874
2022-07-27 20:40:25 +08:00
看样子你没理解 await ,你这样包一层再 let res = hello() 同样会拿到 promise

你得在 async 里面 await 才能拿到返回值,比如

async function hello() {
let res = await Axios.request(options)
// 这个 res 是同步返回值
}

要觉得调用 hello() 麻烦也可以把它写成立即执行的匿名函数
jinliming2
2022-07-27 22:44:48 +08:00
JS 是单线程,Promise 只能由 Runtime 去后台执行然后安排回调。
如果你硬要同步的话,由于单线程,在等待 IO 响应的时候,其他所有代码都没办法跑。
cz5424
2022-07-27 22:45:01 +08:00
直接去掉 async 不行吗?
learningman
2022-07-27 22:48:29 +08:00
写个 spin lock ,强行把异步转成同步就好了捏
aaronlam
2022-07-27 22:53:19 +08:00
await 后面的函数调用返回的就是 promise
bojackhorseman
2022-07-27 22:55:38 +08:00
因为它只是语法🍭,本质还是异步的
yjd
2022-07-28 01:29:05 +08:00
var getData;
(() => {
(async () => {
await Axios.request(options)
.then(res => getData = res.data)
})();
return getData;
})();
DiamondYuan
2022-07-28 01:43:39 +08:00
有办法。 以下都前端黑魔法,不建议使用。 在某些特殊情况下有奇效。



1. 在 nodejs 里可以使用 node-force-sync


const { forceSync } = require('node-force-sync');

const asyncGet = async (url: string) => {
const axios = require('axios');
return (await axios.get(url)).data;
};

const syncGet = forceSync(asyncGet);

const response = syncGet('https://postman-echo.com/get?foo=bar');


2. 在浏览器里可以使用


$.ajax({
type: "GET",
url: remote_url,
async: false
})
nowheremanx
2022-07-28 03:28:42 +08:00
等 axios 调用完之后返回客户端不就好了,也就是 then 或者 await 。
chnwillliu
2022-07-28 04:22:29 +08:00
开一个 worker 然后 shared memory, 然后用 Atomics.wait 挂起等待 worker 完成请求。。。。
geelaw
2022-07-28 05:09:50 +08:00
这个问题和 axios 没有任何关系,JavaScript 不允许同步化异步操作,而且只要 JavaScript 维持单线程模型和 setTimeout 的语义,很难预见同步化异步操作的可能性。

考虑如下代码:

var Axios = {};
Axios.request = function (options) {
return new Promise(function (resolve, reject)
{
setTimeout(function () {
console.log(2);
resolve(3);
}, 1000);
});
};

考虑强行同步

var mySync = function (options)
{
return magic syncronous result of Axios.request(options);
};

那么代码

var excl = mySync();
console.log(1);
console.log(excl);

有矛盾。

一方面,根据 Promise 和 setTimeout 的要求,2 必须在 1 之后( Promise 构造器传入的方法立刻执行,因此 setTimeout 发生在 1 之前,同时 setTimeout 在延迟是 1000 的时候保证传入的方法在当前同步代码块结束后才调用)。另一方面,如果要求 excl 得到 3 的值,那么必须先经过 2 ,但 excl 的值在 1 之前得到。

@DiamondYuan #14 应该注意 node-force-async 得到的结果是错误的——例如传入的方法必须不读取外 scope 的内容,并且返回值会失去类型——这是因为它的原理是同步开一个新的进程执行代码。第二个方法里面是直接从源头杜绝异步。
JounQin
2022-07-28 07:02:44 +08:00
Node 端可以用这个 https://github.com/un-ts/synckit
最近在考虑增加浏览器端端支持。
JounQin
2022-07-28 07:05:02 +08:00
node-force-sync 用的 child_process 完全不用考虑。
fds
2022-07-28 07:45:54 +08:00
```
async function hello() {
let res = await Axios.request(options)
将 res 发送给客户端
}
```

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/869082

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX