代码之家  ›  专栏  ›  技术社区  ›  rink.attendant.6

履行承诺

  •  3
  • rink.attendant.6  · 技术社区  · 6 年前

    在所有承诺都解决的假设下,是异步迭代( for-await-of Promise.all ?

    specification on asynchronous iteration :

    每次访问序列中的下一个值时,我们都隐式地 await 从迭代器方法返回的承诺。

    let pages = [fetch('/echo/json/'), fetch('/echo/html/'), fetch('/echo/xml/')]
    for await (let page of pages) {
        console.log(page)
    }
    

    使用 答应我

    let pages = await Promise.all([fetch('/echo/json/'), fetch('/echo/html/'), fetch('/echo/xml/')])
    
    pages.forEach(page => console.log(page))
    

    它们都并行地获取页面,但我想知道异步迭代是否在所有页面完成获取之前开始循环。我已经尝试过在浏览器的devtools中限制网络来模拟这一点,但任何差异仍然太小,无法引起注意。

    2 回复  |  直到 6 年前
        1
  •  5
  •   Jonas Wilms    6 年前

    异步迭代(用于等待循环)是否比使用Promise.all更快?

    如果其中一个承诺被拒绝,那么Promise.all将立即退出,而循环必须实现该承诺。

    我想知道异步迭代是否在所有页面完成获取之前开始循环。

        2
  •  0
  •   Muhammed Ozdogan    6 年前

    我想你不需要 await 此外,这不是将数据提取和写入控制台的最快方式:

    let pages = Promise.all([fetch('/echo/json/'), fetch('/echo/html/'), fetch('/echo/xml/')])
    pages.then((page) => {console.log(page)});
    

    pages.then() 将等待每一个承诺的解决。

    但是可以像上面那样异步获取数据。把它们写到控制台,而不必在页面前等待。这样地:

     var sequence = Promise.resolve();
     ['/echo/json/','/echo/html/','/echo/xml/'].forEach(function(url) {
       sequence.then(function() {
          return fetch(url);
        })
        .then((data) => {console.log(data)});
      });
    

    但上面的代码并没有考虑页面的顺序。如果书页的顺序是你的事。

    var sequence = Promise.resolve();
    
          // .map executes all of the network requests immediately.
          var arrayOfExecutingPromises =  
          ['/echo/json/','/echo/html/','/echo/xml/'].map(function(url) {
            return fetch(url);
          });
    
         arrayOfExecutingPromises.forEach(function (request) {
        // Loop through the pending requests that were returned by .map (and are in order) and
        // turn them into a sequence.
        // request is a fetch() that's currently executing.
        sequence = sequence.then(function() { 
          return request.then((page) => {console.log('page')});
        });
      });