Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/388.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 多个未连接的异步事件如何等待一个承诺_Javascript_Async Await - Fatal编程技术网

Javascript 多个未连接的异步事件如何等待一个承诺

Javascript 多个未连接的异步事件如何等待一个承诺,javascript,async-await,Javascript,Async Await,我有一个系统,我需要一个来自服务器的id来处理事件。我应该只在第一个事件发生时获取id,但在那之后,我需要为每个后续事件使用相同的id。我知道如何使用async Wait等,所以我有一些类似的代码 var id = ""; async function handleEvent(e) { if (! id ) { let response = await fetch(URL) if (response.ok) { let json

我有一个系统,我需要一个来自服务器的id来处理事件。我应该只在第一个事件发生时获取id,但在那之后,我需要为每个后续事件使用相同的id。我知道如何使用async Wait等,所以我有一些类似的代码

var id = "";
async function handleEvent(e) {
    if (! id ) {
        let response = await fetch(URL)
        if (response.ok) { 
            let json = await response.json();
            id = json.id ;
        }
    }
    // use id to handle event
}
但我的问题是,在收到响应之前,我可能会收到多个事件,因此我会收到多个重叠调用以获取新id


我怎么能有多个对handleEvent的异步调用,第一个处理获取,任何后续调用都等待它完成以访问结果?

不清楚为什么您的函数被参数化为“e”。 我会用更直接的方式来写:

异步函数请求(URL){ let response=fetch(URL) if(response.ok){ 让json=wait response.json(); 返回json.id; } 返回false;
}创建一个函数,以确保使用延迟承诺只对id发出一个请求

consturl='whatever'

让idPromise//so lazy当前接受的响应依赖于一个全局变量,这并不理想。另一种选择是使用类

class-IDManager{
getId(URL){
if(this.id){
返回此.id;
}
this.id=fetch(URL)
把这个还给我
}
}
然后,当您调用
getId
时,您只需等待结果。如果之前没有发出请求,将发送网络请求。如果已经有一个挂起的请求,每个调用都将等待相同的结果。如果承诺已经解决,你会立即得到结果

const idManager=new idManager();
异步函数handleEvent(){
const id=await idManager.getId(URL);
//用身份证做事。
}

这个问题的解决方案与前面的答案略有不同。我想我会发布我最终是如何做到的。来自@phil和@vaelin的答案真的帮助我解决了这个问题

这是我的解决方案

class IDManager {
    async fetchID (resolve,reject ) {
        const response = await fetch( URL, { } ) ;
        const id = await response.json() ;
        resolve( id );
    }
    async getID() {
        if ( this.id === undefined ) {
            if ( this.promise === undefined ) {
                var self = this;
                this.promise = new Promise( this.fetchID ).then( function(id) { self.id = id;} );
            }
            await this.promise;
        }
        return this.id;
    }
}

问题是等待getID调用的获取需要几秒钟的时间。在此期间,经常有多个对getID的调用,所有这些调用都启动了另一次获取。我通过将fetch和response.json调用包装在另一个立即创建的承诺中避免了这种情况,因此避免了重复的承诺。

我假设这就像某种类型的身份验证令牌?它是一个资源令牌,不是身份验证令牌,而是类似的想法。我只需要取一个。你可以用chained创建一个全局承诺。然后保证handleEvent的累积调用顺序,但你真的不应该。您真的应该使用handleEvent返回的承诺。你真正想要的是中止,不是吗?这个函数不仅仅是获取id,它还处理一个事件“e”。它需要id来处理事件。感谢@FZs,我总是忘记OPs代码中的
var id
也是全局的,这取决于用例,是否将其存储在数据结构中(例如,通过url键控)是更好的选择。一个单一的、全球性的
idManager
将不会有任何改进:-)@Bergi我相信这是一个理智的人可能不同意的观点。OP可以通过将其放在自己的模块中来控制对global的访问,我注意到答案现在反映了这一点。另一方面,这会降低你的灵活性。IDManager实例可以使用getter/setter控制对ID变量的访问,并且可以根据需要进行实例化。