Javascript 为什么';不要懒洋洋地等着街区?
我有兴趣理解为什么使用Javascript 为什么';不要懒洋洋地等着街区?,javascript,async-await,Javascript,Async Await,我有兴趣理解为什么使用await立即阻塞,而不是仅在引用awaited值时才延迟阻塞 我希望这是一个启发性的/重要的问题,但我担心这可能被认为超出了本网站的范围-如果是,我会道歉,哭一场,然后把问题带到别处 例如,考虑以下内容: let delayedValue = (value, ms=1000) => { return new Promise(resolve => { setTimeout(() => resolve(val), ms); }); }; (
await
立即阻塞,而不是仅在引用await
ed值时才延迟阻塞
我希望这是一个启发性的/重要的问题,但我担心这可能被认为超出了本网站的范围-如果是,我会道歉,哭一场,然后把问题带到别处
例如,考虑以下内容:
let delayedValue = (value, ms=1000) => {
return new Promise(resolve => {
setTimeout(() => resolve(val), ms);
});
};
(async () => {
let value = await delayedValue('val');
console.log('After await');
})();
(async() => {
let file1 = await readFile('file1dir');
let file2 = await readFile('file2dir');
// ... do things with `file1` and `file2` ...
});
在立即运行的匿名异步函数中,我们只会看到控制台在延迟后说After wait
。为什么这是必要的?考虑到我们不需要解析value
,为什么语言设计者没有决定在这种情况下立即执行console.log
语句
例如,它不同于下面的示例,延迟console.log显然是不可避免的(因为引用了wait
ed值):
我发现lazyawait
阻塞有很多好处——它可以导致不相关操作的自动并行化。例如,如果我想阅读两个文件,然后同时使用这两个文件,并且我不是在学习,我会写以下内容:
let delayedValue = (value, ms=1000) => {
return new Promise(resolve => {
setTimeout(() => resolve(val), ms);
});
};
(async () => {
let value = await delayedValue('val');
console.log('After await');
})();
(async() => {
let file1 = await readFile('file1dir');
let file2 = await readFile('file2dir');
// ... do things with `file1` and `file2` ...
});
这将等待读取第一个文件后再开始读取第二个文件。但实际上它们可以并行读取,javascript应该能够检测到这一点,因为file1
直到稍后才会被引用。当我第一次学习async/await时,我最初的期望是像上面这样的代码会导致并行操作,当这被证明是错误的时候,我有点失望
让这两个文件并行读取仍然有点混乱,即使在这个美丽的ES7世界中也是如此,因为wait
会立即阻塞,而不是懒散地阻塞。您需要执行以下操作(当然比上述操作更混乱):
为什么语言设计人员选择让等待立即阻止而不是懒惰地阻止?
例如,这会导致调试困难吗?将lazyawait
s集成到javascript中会不会太困难?是否存在我没有想到的情况,懒惰的wait
s会导致更混乱的代码、更差的性能或其他负面后果?原因1:JavaScript没有被懒惰地评估。没有检测“何时实际需要某个值”的基础结构
原因2:隐式并行将很难控制。如果我希望我的文件按顺序读取,我将如何编写?改变语法中的一些小东西不应该导致非常不同的评估
让这两个文件并行读取仍然有点混乱
完全不是:
const [file1, file2] = await Promise.all([readFile('file1dir'), readFile('file2dir')]);
您需要执行以下操作
不,您。如果await
表达式从未分配给变量,会产生副作用,而这反过来又需要在下一行代码中使用,那么该表达式呢?在这种情况下,lazyawait
是如何工作的?你可以通过使用承诺而不是await
来完成你所要求的一切。await
的全部要点是你得到了你不满意的行为。懒散地阻止?这意味着什么?异步操作可能(通常也会)有许多副作用,例如寻址前端数据存储、显示隐藏加载指示器等等,使执行顺序不确定将使使用Async
成为竞争条件。当然,你可以重新构造你的代码来解决这个问题,但与此同时,你现在也可以重新构造你的代码,而不引入隐藏的竞争条件。啊,我没有想到会有副作用!