为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

智慧大石 2022-09-02 10:23:19
我有一个系统,我需要来自服务器的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,第一个异步调用处理读取和任何后续调用等待它完成以访问结果?
查看完整描述

4 回答

?
不负相思意

TA贡献1777条经验 获得超10个赞

创建一个函数,以确保仅使用惰性承诺对 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 system

export default initialise

现在,您所要做的就是在任何其他呼叫前面加上前缀,以获取ID,这只会发生一次initialise()


import initialise from 'path/to/initialise'


async function handleEvent(e) {

  const id = await initialise()


  // do stuff with the ID

}


查看完整回答
反对 回复 2022-09-02
?
繁星点点滴滴

TA贡献1803条经验 获得超3个赞

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


class IDManager {

    getId(URL) {

        if (this.id) {

            return this.id;

        }

        this.id = fetch(URL)

        return this.id

    }

}

然后,当您调用 时,您只需等待结果即可。如果之前未发出任何请求,则将发送网络请求。如果已经存在挂起的请求,则每次调用都将等待相同的结果。如果承诺已经解决,您将立即获得结果。getId


const idManager = new IDManager();

async function handleEvent() {

   const id = await idManager.getId(URL);

   // Do stuff with the ID.

}


查看完整回答
反对 回复 2022-09-02
?
呼如林

TA贡献1798条经验 获得超3个赞

不清楚为什么你的函数被“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


查看完整回答
反对 回复 2022-09-02
?
小怪兽爱吃肉

TA贡献1852条经验 获得超1个赞

事实证明,解决这个问题的方法与之前的答案略有不同。我想我会发布我最终如何使它工作。来自@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 中来避免这种情况,从而避免了重复。


查看完整回答
反对 回复 2022-09-02
  • 4 回答
  • 0 关注
  • 81 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信