javascript – 在非异步函数中使用“await”

前端之家收集整理的这篇文章主要介绍了javascript – 在非异步函数中使用“await”前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个异步函数,由我的代码中的某个地方的setInterval运行.此函数定期更新某些缓存.

我还有一个不同的同步函数需要检索值 – 最好是从缓存中检索,如果它是缓存未命中,那么从数据源开始
(我意识到以同步方式进行IO操作是不明智的,但我们假设在这种情况下需要这样做).

我的问题是我希望同步函数能够等待来自异步函数的值,但是不可能在非异步函数中使用await关键字:

function syncFunc(key) {
    if (!(key in cache)) {
        await updateCacheForKey([key]);
    }
}

async function updateCacheForKey(keys) {
    // updates cache for given keys
    ...
}

现在,通过将updateCacheForKey中的逻辑提取到新的同步函数中,并从现有函数调用此新函数,可以轻松避免这种情况.

我的问题是为什么首先绝对防止这个用例?我唯一的猜测是它与“白痴防范”有关,因为在大多数情况下,从同步函数等待异步函数错误的.但我认为它有时会有其有效的用例我错了吗?

(我认为这也可以通过使用Task.Wait在C#中实现,尽管我可能会在这里混淆一​​些事情).

解决方法

My problem is I’d like the synchronous function to be able to wait for a value from the async one…

他们不能,因为:

> JavaScript基于由线程处理的“作业队列”工作,其中作业具有运行到完成语义,并且
> JavaScript实际上并没有异步功能(真的 – 坚持这个……)

作业队列(事件循环)在概念上非常简单:当需要完成某些事情(脚本的初始执行,事件处理程序回调等)时,该工作将被放入作业队列中.为该作业队列提供服务的线程获取下一个待处理作业,将其运行至完成,然后返回下一个作业. (当然,它比这更复杂,但这足以满足我们的目的.)因此,当一个函数调用时,它被调用作为处理作业的一部分,并且作业总是在下一个作业运行之前处理完成.

运行完成意味着如果作业调用了一个函数,那么该函数必须在作业完成之前返回.当线程运行以执行其他操作时,作业不会在中间暂停.这使得代码变得非常简单,可以正确地编写和推理,而不是在其他事情发生时,作业可能会被暂停. (再次它比这更复杂,但这又足以满足我们的目的.)

到现在为止还挺好.这有什么关于没有真正拥有异步功能的东西?!

虽然我们谈论“同步”和“异步”函数,甚至有一个async关键字我们可以应用于函数,但函数调用在JavaScript中始终是同步的.异步函数并不存在.我们有同步函数可以设置环境稍后会调用的回调(通过排队作业).

我们假设updateCacheForKey看起来像这样:

async function updateCacheForKey(key) {
    const value = await fetch(/*...*/);
    cache[key] = value;
    return value;
}

在幕后,真正做的是:

function updateCacheForKey(key) {
    return fetch(/*...*/).then(result => {
        const value = result;
        cache[key] = value;
        return value;
    });
}

它要求浏览器启动获取数据的过程,并向其注册回调(通过那时),以便浏览器在数据返回时调用,然后退出,从此返回promise.尚未获取数据,但updateCacheForKey已完成.它已经回来了.它同步完成了它的工作.

稍后,当提取完成时,浏览器会将作业排队以调用该保证回调;当从队列中获取该作业时,将调用回调,并且其返回值用于解析随后返回的promise.

My question is why absolutely prevent this use case in the first place?

让我们看看它会是什么样子:

>线程获取一个作业,该作业涉及调用syncFunc,它调用updateCacheForKey. updateCacheForKey要求浏览器获取资源并返回其promise.通过这种非异步等待的魔力,我们同步等待该承诺得到解决,从而阻止了这项工作.
>在某些时候,浏览器的网络代码完成检索资源并对作业进行排队,以调用我们在updateCacheForKey中注册的promise回调.
>再也没有发生过. 原文链接:https://www.f2er.com/js/158338.html

猜你在找的JavaScript相关文章