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

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


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。


我怎样才能有多个异步调用来处理Event,第一个异步调用处理读取和任何后续调用等待它完成以访问结果?


智慧大石
浏览 85回答 4
4回答

不负相思意

创建一个函数,以确保仅使用惰性承诺对 id 发出一个请求。const URL = 'whatever'let idPromise // so lazy 🦥const getId = async () => {  const response = await fetch(URL)  if (!response.ok) {    throw response  }  return (await response.json()).id}const initialise = () {  if (!idPromise) {    idPromise = getId()  }  return idPromise}// and assuming you're using a module systemexport default initialise现在,您所要做的就是在任何其他呼叫前面加上前缀,以获取ID,这只会发生一次initialise()import initialise from 'path/to/initialise'async function handleEvent(e) {  const id = await initialise()  // do stuff with the ID}

繁星点点滴滴

当前接受的响应依赖于全局变量,这并不理想。另一种选择是使用类。class IDManager {    getId(URL) {        if (this.id) {            return this.id;        }        this.id = fetch(URL)        return this.id    }}然后,当您调用 时,您只需等待结果即可。如果之前未发出任何请求,则将发送网络请求。如果已经存在挂起的请求,则每次调用都将等待相同的结果。如果承诺已经解决,您将立即获得结果。getIdconst idManager = new IDManager();async function handleEvent() {   const id = await idManager.getId(URL);   // Do stuff with the ID.}

呼如林

不清楚为什么你的函数被“e”参数化。我会用更直接的方式写它:async function request(URL) {       let response = fetch(URL)        if (response.ok) {             let json = await response.json();            return json.id;        }        return false;}然后,如果您的呼叫顺序很重要,请逐个写下它们。如果没有,那么你可以使用Promise.all(Promise.allSettled maybe)一次运行它们。https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

小怪兽爱吃肉

事实证明,解决这个问题的方法与之前的答案略有不同。我想我会发布我最终如何使它工作。来自@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 调用包装在另一个立即创建的 promise 中来避免这种情况,从而避免了重复。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript