【问题标题】:Conditional/dynamic array promise all条件/动态数组承诺所有
【发布时间】:2018-05-11 12:13:57
【问题描述】:

我有一个带有一组 promise 的函数,该数组可以有 1 到 X 个 promise。

这些承诺基于条件进入数组。

我希望能够区分每个结果来自哪个 API,但我无法实现一种干净的方式来做到这一点

let promises = [];

if (false) {
  let promise1 = request(toUrl);
  promises.push(promise1);
}
if (true) {
  let promise2 = request(toUrl);
  promises.push(promise2);
}

if (false) {
  let promise3 = request(toUrl);
  promises.push(promise3);
}

if (true) {
  let promise4 = request(toUrl);
  promises.push(promise4);
}

try {
  let result = await Promise.all(promises);
} catch (error) {
  console.log(error);
}

所以,如果一切顺利,结果将是一个结果数组。不知道哪一个条件为真,我怎么知道 result[0] 是 promise1、promise2 还是 promise3 的结果?

【问题讨论】:

  • 为什么不有条件地将 url 推送到数组?然后简单地Promise.all (urls.map (request))
  • 添加网址不会给他Promise.all then 请求完成的网址
  • @Suren Srapyan 你错了,请参考 MDN。 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • 我的意思是,在得到结果后,你得到了 url 数组的结果,但你不知道究竟有哪些 url。我的意思是 urls 添加到带有条件的数组中。是的,如果解决了所有问题,您都拥有,但实际上哪些网址被添加到您无法在 Promise.all 检测到的数组中

标签: javascript promise async-await


【解决方案1】:

您可以在request(url) 的回复中添加有关承诺的其他信息,例如

const promise1 = request(url).then(res => ({ res: res, promise: 'promise1' }))

Promise.all(),您将获得上述形式的承诺值,并可以检测到哪些承诺已解决。

示例

const promises = [];

if(true) {
   const promise1 = fetch('https://jsonplaceholder.typicode.com/posts/1').then(res => ({ res: res, promise: 'promise1' }));
   promises.push(promise1);
}

if(false) {
   const promise2 = fetch('https://jsonplaceholder.typicode.com/posts/2').then(res => ({ res: res, promise: 'promise2' }));
   promises.push(promise2);
}

Promise.all(promises).then(res => console.log(res));

【讨论】:

  • 酷,喜欢它。还有一个问题需要澄清有关承诺,将 .then 并将回调函数调用到 .then 之后意味着我正在执行承诺,对吗?
  • 当你创建一个 Promise 时,它​​已经开始执行了。添加then不代表你执行了
  • 我的意思是,如果 promise 是函数,则 request(url) 是函数,而 request(url).then(res => res) 是函数(),对吗?
  • 两者都返回你的承诺,但最后一个也增加了一些其他的工作。如果我理解你是正确的
  • 哦,我明白了,感谢您的所有帮助,非常感谢,早上好!
【解决方案2】:

我使用了一个带有名称键的 Promise 对象映射,以识别哪个解析对应于哪个 Promise。

const promises = {};

const mapResolveToPromise = res => Object.fromEntries(
  Object.entries(promises).map(([key], index) => [key, res[index]])
);

promises.promise1 = fetch('https://jsonplaceholder.typicode.com/posts/1');
promises.promise2 = fetch('https://jsonplaceholder.typicode.com/posts/2');

Promise.all(Object.values(promises))
  .then(mapResolveToPromise)
  .then(res => {
    console.log(res.promise1.url);
    console.log(res.promise2.url);
  });

【讨论】:

    【解决方案3】:

    在我看来,我们可以通过使用以下代码来简化问题的复杂性 -

    let promises = [];
    
    let truthyValue = true,
      falsyvalue = true;
      
     let [promise1, promise2, promise3, promise4] = await Promise.all([
        truthyValue ? request(toUrl) : Promise.resolve({}),
        truthyValue ? request(toUrl) : Promise.resolve({}),
        falsyValue ? request(toUrl) : Promise.resolve({}),
        falsyValue ? request(toUrl) : Promise.resolve({})
     ]);
     
     // promise1 will be called only when truthyValue is set
     if (promise1) {
      // do something
     }
     
      // promise2 will be called only when truthyValue is set
      if (promise2) {
      // do something
     }
     
      // promise3 will be called only when falsyValue is set
      if (promise3) {
      // do something
     }
       // promise4 will be called only when falsyValue is set
      if (promise4) {
      // do something
     }

    【讨论】:

      【解决方案4】:

      为什么所有的推送,你都可以内联构造数组。

      doPromiseStuff = async ({ thing = true }) => {
        const urls = ['', '', '', ''];
      
        return await Promise.all([
          thing ? request(urls[1]) : request(urls[2]),
          thing ? request(urls[3]) : request(urls[4])
        ]);
      }
      

      【讨论】:

        【解决方案5】:

        我遇到了类似的问题,总是要调用不同数量的异步函数。 我不想要的是在promise.all() 之前开始承诺工作。

        所以我在一个数组中收集了函数指针。

        例如:

        async function first() {
            return new Promise((resolve)=> setTimeout(resolve,1000,99));
        }
        
        async function second() {
            return new Promise((resolve)=> setTimeout(resolve,1500,100));
        }
        
        let x = [first, second];
        // x is transformed into an array with then executed functions
        await Promise.all(x.map(x=>x()))
        
        

        结果是:

        [
            99,
           100
        ]
        

        希望这会有所帮助,并且我理解了上述问题... :)

        【讨论】:

          猜你喜欢
          • 2017-07-02
          • 2013-10-06
          • 2014-08-30
          • 2017-07-13
          • 2018-08-02
          • 2017-11-07
          • 1970-01-01
          • 2015-06-22
          • 2018-02-25
          相关资源
          最近更新 更多