代码之家  ›  专栏  ›  技术社区  ›  Shawn Tabrizi

将两个承诺的结果输出到一个对象中

  •  0
  • Shawn Tabrizi  · 技术社区  · 7 年前

    我有两个异步函数来创建承诺。两个函数使用相同的输入 i .

    async function1(i) {}
    async function2(i) {}
    

    我将使用不同的输入值多次调用这些函数,并希望尽可能提高代码的效率,因此我希望将承诺排队,并使用 Promise.all() .

    但是,我希望得到一个单独的结果作为我的最终输出,它将是一个这样的对象数组:

    [
      {
        input: i,
        result1: result1,
        result2: result2
      },
      ...
    ]
    

    我通过两个步骤完成了这项工作:

    async function function1(i) {
      return i * i
    }
    
    async function function2(i) {
      return i * i * i
    }
    
    async function main() {
      var promises = []
    
      for (let i = 0; i < 10; i++) {
        let promise = function1(i)
          .then(function(result1) {
              return {i:i, result1:result1}
          });
    
        promises.push(promise)
      }
    
      var final = await Promise.all(promises)
      
      var promises2 = [];
      
      for (let i = 0; i < 10; i++) {
        let promise = function2(i)
        .then (function(result2) {
          final[i]['result2'] = result2;
        });
        
        promises2.push(promise);
      }
      
      await Promise.all(promises2)
      
      console.log(final)
    
    }
    
    main()

    但是,我觉得这可以用一个 承诺。全部() 。你能告诉我怎么做吗?

    2 回复  |  直到 7 年前
        1
  •  1
  •   laptou    7 年前

    async function function1(i)
    {
        return i * i
    }
    
    async function function2(i)
    {
        return i * i * i
    }
    
    async function main()
    {
        const promises = [];
    
        for (let i = 0; i < 10; i++)
            promises.push(function1(i), function2(i));
    
        const results = await Promise.all(promises);
        const data = [];
    
        for (let i = 0; i < 10; i++)
        {
            const [result1, result2] = results.slice(i * 2, i * 2 + 2);
            data.push({ i, result1, result2 });
        }
    
        console.log(data);
    }
    
    main();

    这应该能顺利、迅速地进行。功能 function1 function2 返回 Promise 如果你不这样做 await 把它们推到 promises 数组是不言而喻的。

    那你就等着吧 Promise.all 直到所有20个承诺都完成。最后,第二个循环贯穿于返回的承诺。

    在我的代码中我使用 destructuring assignments . 我假设您可以使用这些函数,因为您使用的是异步函数,这意味着您可以使用ES2017。

        2
  •  0
  •   Shawn Tabrizi    7 年前

    编辑:333的答案是正确的,不是我的。此解决方案将在队列中有两个批次。

    我想我明白了:

    console.log("start")
    
    function sleep(ms) {
      return new Promise(resolve => setTimeout(resolve, ms));
    }
    
    async function function1(i) {
      await sleep(2000);
      return i * i
    }
    
    async function function2(i) {
      await sleep(2000);
      return i * i * i
    }
    
    async function main() {
      var promises = []
    
      for (let i = 0; i < 10; i++) {
        let a = function1(i);
        
        let b = function2(i);
        
        let promise = Promise.all([a,b]).then(
          function([resulta,resultb]) {
              return {i:i, result1: resulta, result2: resultb}
          });
    
        promises.push(promise)
      }
    
      var final = await Promise.all(promises)
      
      
      console.log(final)
    
    }
    
    main()

    注意,我添加了一个sleep函数来测试这些函数的并行化。每件事都在2秒钟内完成,所以我认为它是优化的。

    推荐文章