亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何使可鏈接的異步函數并行工作,然后只等待最后一個函數?

如何使可鏈接的異步函數并行工作,然后只等待最后一個函數?

牛魔王的故事 2022-07-01 16:57:09
我想做以下事情:const contextSeeder = new ContextSeeder(context);let props = (await (await contextSeeder.withList()).withUser()).get();但理想情況下,這看起來像:const contextSeeder = new ContextSeeder(context);let props = await contextSeeder.withList().withUser().get();withList()并且withUser()都會進行 API 調用。所以理想情況下它們應該并行運行。他們都修改了類中的一個對象,該對象是返回值(可能存在競爭條件嗎?)因此,鑒于我將這兩個“加載器”稱為“加載器”,我希望它.get()成為實際必須等待的那個。可能嗎?因為在第一種方式中,它看起來會一個一個地處理(因為兩個調用中的等待)我在一個內部運行它async function,并且我需要在函數返回時出現這些數據。我不能做一個.then()謝謝export default class ContextSeeder {    context = {};    serverContext;    constructor(serverContext = undefined) {        this.serverContext = serverContext;    }    withUser = async (listId = undefined) => {        let userContext = {};        await UserContextSeeder(this.serverContext).then(context => {userContext = context});        this.context = {...this.context, user: userContext}        return this;    }    withList = async (userId = undefined) => {        let listContext = {};        await ListContextSeeder(context).then(context => {listContext = context});        this.context = {...this.context, list: listContext}        return this;    }    get = () => {        return this.context;    }}
查看完整描述

3 回答

?
茅侃侃

TA貢獻1842條經驗 獲得超22個贊

如果您想并行運行請求,則在調用 .get() 之前等待它們都完成,您可以嘗試使用以下代碼Promise.all:


// we wait for both promises to finish

await Promise.all([contextSeeder.withList(), contextSeeder.withUser()]);

// they're both finished so we can get it now

let props = contextSeeder.get();


查看完整回答
反對 回復 2022-07-01
?
猛跑小豬

TA貢獻1858條經驗 獲得超8個贊

以下內容一一開始異步檢索,然后使用Promise.all. 最后,將結果解構,然后添加到要返回的對象中。


我認為這是對您的代碼的簡化,因為中間狀態不會公開共享。


我會重命名ListContextSeeder并UserContextSeeder成為更慣用的東西。大寫的名稱通常保留給構造函數。


export default async function seedContext({ serverContext, listId, userId }) {

  const p1 = ListContextSeeder(serverContext, listId)

  const p2 = UserContextSeeder(serverContext, userId)

  const [list, user] = await Promise.all([p1, p2])

  return { list, user }

}


查看完整回答
反對 回復 2022-07-01
?
千萬里不及你

TA貢獻1784條經驗 獲得超9個贊

出于此答案的目的,我將忽略您沒有使用 userId 或 listId 的事實。

您可以使用以下內容簡化代碼:


export default class ContextSeeder {

    context = {};

    serverContext;


    constructor(serverContext = undefined) {

        this.serverContext = serverContext;

    }


    withList = async (listId = undefined) => {

        let seededUserContext = await UserContextSeeder(this.serverContext);


        this.context = {...this.context, user: seededUserContext}


        // Not needed unless you still want to chain them

        // return this;

    }


    withUser = async (userId = undefined) => {

        let seededListContext = await ListContextSeeder(context);


        this.context = {...this.context, list: seededListContext}


        // Not needed unless you still want to chain them

        // return this;

    }


    get = () => {

        return this.context;

    }

}

然后,您可以使用 Promise.all() 等待兩者的解決:


// They now run in "parallel"

await Promise.all([contextSeeder.withList(), contextSeeder.withUser());

let props = contexSeeder.get();

更新

根據下面 Ben Aston 的回答,另一個改進是將此行為封裝在另一個內部方法中,傳遞一個中間上下文,并且只有在兩個調用都完成后才設置實際上下文。


export default class ContextSeeder {

  context = {};

  serverContext;


  constructor(serverContext = undefined) {

    this.serverContext = serverContext;

  }


  withList = async (listId = undefined, intermediateContext) => {

    let seededUserContext = await UserContextSeeder(this.serverContext);


    // No spread operator needed, just set the property

    intermediateContext.user = seededUserContext;


    // Not needed unless you still want to chain them

    // return this;

  };


  withUser = async (userId = undefined, intermediateContext) => {

    let seededListContext = await ListContextSeeder(context);


    // No spread operator needed, just set the property

    intermediateContext.list = seededListContext;


    // Not needed unless you still want to chain them

    // return this;

  };


  seedContext = async (userId, listId) => {

    let intermediateContext = {};


    await Promise.all([

      withUser(userId, intermediateContext),

      withList(listId, intermediateContext)

    ]);


    this.context = intermediateContext;

  }


  get = () => {

    return this.context;

  };

}

然后,只需等待 seedContext:


await contextSeeder.seedContext(userId, listId);

let props = contextSeeder.get();


查看完整回答
反對 回復 2022-07-01
  • 3 回答
  • 0 關注
  • 116 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號