【问题标题】:How to use fetch within a for-loop, wait for results and then console.log it如何在 for 循环中使用 fetch,等待结果,然后 console.log 它
【发布时间】:2022-03-16 15:00:35
【问题描述】:

我有这个问题:我想在一个 for 循环中进行多次 fetch 调用。调用次数取决于用户输入(在我的示例中,我有三个)。我怎样才能让它遍历所有的 fetch 请求,然后 console.log 关闭电话号码?

函数 getPosts(){

  let url = ["https://www.freecodecamp.org", "https://www.test.de/, http://www.test2.com"];
  let array = new Array;

  for (let i = 0; i < url.length; i++) {
    console.log(url[i]);
    fetch(url[i])
    .then(res => {return res.text(); })
    .then(res => {
            let reg = /\<meta name="description" content\=\"(.+?)\"/;
            res = res.match(reg);
            array.push(res);
            console.log(res);
          }
    )
    .catch(status, err => {return console.log(status, err);})
  }
  console.log (array.length);
  }

它 console.logs 0 而不是 3,因为它不会等待所有的 promise 都被解决。我怎样才能使它成为console.log 3? 如果您知道解决方案,请帮助我。

【问题讨论】:

    标签: javascript fetch-api


    【解决方案1】:

    你不能调用console.log(array.length),直到之后所有的promise都完成了。那么为什么不这样呢?

    let url = ["https://www.freecodecamp.org", "https://www.test.de/, http://www.test2.com"];
      let array = new Array;
      var fetches = [];
      for (let i = 0; i < url.length; i++) {
        console.log(url[i]);
        fetches.push(
          fetch(url[i])
          .then(res => {return res.text(); })
          .then(res => {
                let reg = /\<meta name="description" content\=\"(.+?)\"/;
                res = res.match(reg);
                array.push(res);
                console.log(res);
              }
          )
          .catch(status, err => {return console.log(status, err);})
        );
      }
      Promise.all(fetches).then(function() {
        console.log (array.length);
      });
      }
    

    Promise.all 等待所有提取完成,然后它会打印 #。

    【讨论】:

    • 感谢您的想法。它确实有效,但前提是所有获取请求都成功解决...如果其中一个获取请求失败,你知道我如何拥有 console.log 吗?
    • Promise.all(fetches).then(function() { console.log (array.length); }).catch(function(e){ todo: log error e}) ?跨度>
    【解决方案2】:

    您可以将 async/await 与 try/catch 一起使用:

    async function getPosts(){
      let array = [];
      let url = ["https://www.freecodecamp.org", "https://www.test.de/", "http://www.test2.com"];
      let reg = /\<meta name="description" content\=\"(.+?)\"/;
      for (let i = 0; i < url.length; i++)   {
        console.log('fetching',url[i]);
        try {
          let p1 = await fetch(url[i]);
          let p2 = await p1.text();
          let res = p2.match(reg);
          array.push(res);
          console.log('adding',res);
        }
        catch (e) {
          console.error(e.message);
        }
      };
      console.log ('length',array.length);
    };
    
    getPosts().then(()=>{console.log('done')});

    【讨论】:

    • 我认为这个想法不是等待 fetch 完成然后再进入循环中的下一个?
    【解决方案3】:

    您可以尝试链接您的承诺,尝试以下操作:

    function getPosts(){
    
      let url = ["https://www.freecodecamp.org", "https://www.test.de/, http://www.test2.com"];
      let array = new Array;
      var promise = Promise.resolve();
      for (let i = 0; i < url.length; i++) {
        console.log(url[i]);
        promise = promise.then(fetch(url[i]))
        .then(res => {return res.text(); })
        .then(res => {
                let reg = /\<meta name="description" content\=\"(.+?)\"/;
                res = res.match(reg);
                array.push(res);
                console.log(res);
              }
        )
        .catch(status, err => {return console.log(status, err);})
      }
      promise.then(function(response){
        console.log (array.length);
      });
    }

    【讨论】:

      【解决方案4】:

      您可以使用 async await ( async: function, await: operator )。等待操作员只是等待承诺被解决。第一个承诺将被解决,然后它将转移到另一个承诺。此外,如果它在任何 fetch 中发现错误,它会立即捕获错误。

      【讨论】:

        【解决方案5】:

        你应该使用 Promise,Promise 是一个值的代理,在创建 Promise 时不一定知道。它允许您将处理程序与异步操作的最终成功值或失败原因相关联。这让异步方法可以像同步方法一样返回值:异步方法不是立即返回最终值,而是返回一个承诺,以便在未来某个时间点提供该值。

        const fetch = require('node-fetch')
        let url = ["https://www.freecodecamp.org", "https://www.test.de/, http://www.test2.com"];
        let array = new Array;
        function get(url) {
          return new Promise((resolve, reject) => {
            fetch(url)
              .then(res => { return res.text(); })
              .then(res => {
                let reg = /\<meta name="description" content\=\"(.+?)\"/;
                res = res.match(reg);
                resolve(res)
                //console.log(res);
              }
              )
              .catch(err => { reject(err) })
          });
        }
        async function result() {
          for (let i = 0; i < url.length; i++) {
            const value = await get(url[i]);
            array.push(value)
        
          }
          console.log(array.length)
        }
        
        result()
        

        ==> array.length = 2,

        【讨论】:

        • 感谢您的意见。我怎么写那个承诺
        猜你喜欢
        • 2021-06-17
        • 2021-10-30
        • 2022-10-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-10
        • 1970-01-01
        相关资源
        最近更新 更多