我获得了一些解释JS中异步事件的教育文献......
采用以下示例,其中server1与运行网站的服务器不同,getData()函数将执行复杂的SQL查询,然后返回大型数据集:
var data = server1.getData();
console.log(data);
我们几乎可以肯定控制台会说
undefined
。这是因为第二行代码将在返回getData()的结果之前执行。
我的理解是,只有当函数返回并且其返回值分配给data
时才会执行第二行。实际上,如果getData()返回一个大型数据集',那么当我们到达第二行data
时,将会是一个大型数据集'。
可以像这样推迟作业吗?我非常熟悉远程服务器的异步调用并通过回调处理它们。但我相信JS中的一个简单函数调用将返回一次(最多),代码基本上是单线程执行并顺序执行。
这个文档在尝试解释异步编程的缺陷时是否有些误导?
答案 0 :(得分:1)
该文件可能是误导性的,或故意构成一种无法工作的情况,以解释为什么它不会起作用......无论如何我都会误导。
JavaScript是单线程的 - 因此从事件队列中调出的任何内容必须运行完成并返回事件队列(任务管理器),然后才能开始另一个调用。
var data = server1.getData();
console.log(data);
可以返回大量数据,当且仅当获取数据被请求作为同步操作时,并进一步提供服务器" server1"允许cross origin requests(假设"不同的服务器"表示不同的域,协议或端口)。严重阻止同步数据请求,因为它们会在请求完成之前停止响应网页。如果以这种方式编码,则data
的值仅为undefined
故意选择作为值来表示"没有可用的数据"。
ECMAScript 2017 中引入的await
运算符可以等待异步结果的承诺变为满足,并将结果延迟分配给变量。但用法如
var data = await server1.getData();
console.log(data);`
具有阻止其在示例中使用的限制:它只能在async
函数内使用,async
函数返回Promise对象。因此,即使server1.getData
方法被写为async
函数,并且内部使用await
等待数据到达,也将其分配给变量然后从函数返回,返回async
函数的值未返回到其调用者,但用于填充实际调用时返回的承诺。
server1.getData().then( data=>console.log(data)).catch(err=>console.error(err));
是如果getData
返回一个promise,异步操作可能被编码为有效的方式。如果被调用,则.then
和.catch
提供的回调函数将在一段时间后异步调用。这意味着执行上述代码的代码可以返回事件循环,并在查询结果发送回请求网页之前让其他事情发生。
至于
我们几乎可以肯定控制台会说未定义。
使用提供的代码?不可以。在当前(ECMA脚本版本6或更高版本)浏览器的代码中,我们几乎可以肯定控制台会说Promise { <state>: "pending" }
或类似。