javascript – 有没有办法用async / await而不是Promise返回一个值?作为同步功能吗
作者:互联网
首先,我熟悉异步/同步功能的概念.
还有很多与我有关的问题.但我无法在任何地方找到答案.
所以问题是:
有没有办法使用async / await返回值而不是Promise?作为同步功能吗.
例如:
async doStuff(param) {
return await new Promise((resolve, reject) => {
setTimeout(() => {
console.log('doStuff after a while.');
resolve('mystuffisdone'+param);
}, 2000);
});
}
console.log(doStuff('1'));
获取此函数值的唯一方法是使用.then函数.
doStuff('1').then(response => {
console.log(response); // output: mystuffisdone1
doOtherStuffWithMyResponse(response);
// ...
});
现在,我想要的是:
const one = doStuff('1');
console.log(one) // mystuffisdone1
const two = doStuff('2');
console.log(two) // mystuffisdone2
为了解释自己,我有一个充满回调的异步库.我可以通过使用Promises和async / await来伪造同步行为,将此异步行为转换为同步行为.
但是仍然存在一个问题,它最终仍然是异步的;超出异步函数范围.
doStuff('1').then((r) => {console.log(r)};
console.log('Hello wolrd');
它将导致:Hello world然后mystuffisdone1.这是使用async / await函数时的预期行为.但这不是我想要的.
现在我的问题是:有没有办法在没有关键字异步的情况下做同样的事情?要使代码同步?如果不可能,为什么?
编辑:
谢谢你的回答,我想我的问题并不是一成不变的.要清除我的想法,这是我对@Nikita Isaev的回答.
“我理解为什么所有的I / O操作都是异步完成的;或者是并行完成的.但我的问题更多的是为什么引擎不会以异步方式阻塞同步函数的调用者?我的意思是const a = doStuff(…)是一个Promise.我们需要调用.then来获得这个函数的结果.但是为什么JavaScript或Node引擎不会阻塞调用者(只是调用它的块).如果可能的话,我们可以做const a = doStuff(…),等待并在不阻塞主线程的情况下得到结果.正如async / await那样,为什么没有同步/等待的地方?“
希望现在更清楚,随意评论或者问什么:)
编辑2:
答案原因的所有精确性都在接受答案的评论中.
解决方法:
有一些hacky方法可以做到所需的,但这将是一种反模式.我会试着解释一下.回调是javascript中的核心概念之一.当您的代码启动时,您可以设置事件监听器,计时器等.您只需告诉引擎安排一些任务:“当A发生时,执行B”.这就是异步.但是回调是丑陋的,难以调试,这就是为什么推出promises和async-await的原因.重要的是要理解这只是一个语法shugar,使用async-await时你的代码仍然是异步的.由于javascript中没有线程,等待某些事件触发或某些复杂的操作以同步方式完成会阻塞整个应用程序. UI或服务器将停止响应任何其他用户交互,并将继续等待单个事件触发.
现实案例:
例1.
假设我们有一个Web UI.我们有一个按钮,可以在点击时从服务器下载最新信息.想象一下,我们是同步做到的.怎么了?
myButton.onclick = function () {
const data = loadSomeDataSync(); // 0
useDataSomehow(data);
}
一切都是同步的,代码是平的,我们很高兴.但用户不是.
javascript进程只能在特定时刻执行单行代码.用户将无法单击其他按钮,查看任何动画等,应用程序卡在等待loadSomeDataSync()完成.即使这持续3秒,这是一个糟糕的用户体验,你既不能取消也不能看到进展,也不能做其他事情.
例2.
我们有一个node.js http服务器,拥有超过100万用户.对于每个用户,我们需要执行持续5秒的繁重操作并返回结果.我们可以以同步或异步方式完成.如果我们在异步中执行会发生什么?
>用户1连接
>我们开始执行用户1的繁重操作
>用户2连接
>我们返回用户1的数据
>我们开始执行用户2的繁重操作
> ……
即我们并行完成所有事情.现在假设我们以同步的方式进行繁重的操作.
>用户1连接
>我们开始为用户1执行繁重的操作,其他人都在等待它完成
>我们返回用户1的数据
>用户2连接
> ……
现在假设繁重的操作需要5秒才能完成,而我们的服务器处于高负载状态,它拥有超过100万用户.最后一个将不得不等待近500万秒,这绝对不行.
这就是为什么:
>在浏览器和服务器API中,大多数i / o操作都是异步的
>开发人员努力使所有繁重的计算异步,甚至React以异步方式呈现.
标签:javascript,asynchronous,synchronous 来源: https://codeday.me/bug/20190701/1348049.html