【问题标题】:How to concat two called endpoints to one string and print it in console如何将两个调用端点连接到一个字符串并在控制台中打印
【发布时间】:2019-03-26 15:23:27
【问题描述】:

我的函数必须同时调用两个端点并将它们连接到一个字符串中。我的代码只是一个同时获取两个端点并在控制台中打印的函数。 但是相同的函数必须将它们连接到一个字符串。 我尝试创建包含每个调用的分隔变量,然后简单地将它们连接起来,但结果并没有什么不同。 我读了几个小时,我看不到,即使是最小的小费。 编辑:请注意每个端点都是一个实际的数组。

    function endpointsToOneString() {
        const Http = new XMLHttpRequest();
        const url = 'https://baconipsum.com/api/?type=all-meat&paras=3&start-with-lorem=1&format=json';
        Http.open("GET", url);
        Http.send();

        Http.onreadystatechange = function () {
            if (this.readyState == 4 && this.status == 200) {
                console.log(Http.responseText)
            }
        }


        const HttpTwo = new XMLHttpRequest();
        const urlTwo = 'https://baconipsum.com/api/?type=all-meat&paras=3&start-with-lorem=1&format=json';
        HttpTwo.open("GET", urlTwo);
        HttpTwo.send();

        HttpTwo.onreadystatechange = function () {
            if (this.readyState == 4 && this.status == 200) {
                console.log(Http.responseText)
            }
        }
    }

    endpointsToOneString();

【问题讨论】:

    标签: javascript endpoint


    【解决方案1】:

    在这种情况下,您应该使用javascriptPromise 功能。

    Here 你可以学习如何使用你的原生 XHR。此外,Here 您可以找到有关承诺链的信息。 我刚刚在您的代码中添加了Promise,但需要对其进行重构。

    更新:从评论中,您希望您的回复文本为纯字符串。但我们实际上得到了一个 JSON 数组作为响应。因此,我们需要使用JSON.parse() 函数对其进行解析,使其成为一个数组对象。然后我们需要使用.join() 方法将数组的所有元素连接成一个字符串。请看下面的代码:

    function endpointsToOneString() {
        var requestOne = new Promise(function(resolve, reject){
            const Http = new XMLHttpRequest();
            const url = 'https://baconipsum.com/api/?type=all-meat&paras=3&start-with-lorem=1&format=json';
            Http.open("GET", url);
            Http.onload = function () {
            if (this.status >= 200 && this.status < 300) {
                resolve(Http.response);
            } else {
                reject({
                status: this.status,
                statusText: Http.statusText
                });
            }
            };
            Http.onerror = function () {
            reject({
                status: this.status,
                statusText: Http.statusText
            });
            };
            Http.send();
        });
    
        var requestTwo = new Promise(function(resolve, reject){
            const HttpTwo = new XMLHttpRequest();
            const urlTwo = 'https://baconipsum.com/api/?type=all-meat&paras=3&start-with-lorem=1&format=json';
            HttpTwo.open("GET", urlTwo);
            HttpTwo.onload = function () {
            if (this.status >= 200 && this.status < 300) {
                resolve(HttpTwo.response);
            } else {
                reject({
                status: this.status,
                statusText: HttpTwo.statusText
                });
            }
            };
            HttpTwo.onerror = function () {
            reject({
                status: this.status,
                statusText: HttpTwo.statusText
            });
            };
            HttpTwo.send();
        });
    
    
        Promise.all([
            requestOne,
            requestTwo
        ]).then(function(result){
        	var response = JSON.parse(result[0]).join();
          response += JSON.parse(result[1]).join();
          console.log(response);
        });
    }
    endpointsToOneString();

    【讨论】:

    • 我使用了这样的承诺(在我朋友的帮助下)。这些端点是一个数组。我需要连接它们并加入。我返回 undefined 给我...jsfiddle.net/up7fm4ob
    • @IzaAdamska 我已经编辑了我的答案。你能检查一下当前版本吗?但是,我已根据您的格式格式化了我的代码。 See this fiddle。它正在工作!
    • 我仍然看到两个数组彼此相邻 - 没有解决方案可以从这两个数组端点获得一个实际的 STRING 吗?就像......基本上我们使用 concat() 和 join() 方法来操作数组......我们不能以某种方式使用它吗?
    • @IzaAdamska 我已经更新了我的答案。请立即检查。
    • 这是我想要达到的结果。我相信我并不完全理解这段代码,但是 - 这是我第一份工作的招聘任务 - 我只学习了几个月的 JavaScript。现在我将研究这段代码,以确保我将来能够使用它。非常感谢您的努力!
    【解决方案2】:

    我了解您想要连接两个并行请求的结果。在这种情况下,您可以使用 axios 之类的库。来自他们的docs

    function getUserAccount() {
      return axios.get('/user/12345');
    }
    
    function getUserPermissions() {
      return axios.get('/user/12345/permissions');
    }
    
    axios.all([getUserAccount(), getUserPermissions()])
      .then(axios.spread(function (acct, perms) {
        // Both requests are now complete
      }));
    

    所以对于你的例子:

    function getEndpoint1() {
      return axios.get('https://baconipsum.com/api/?type=all-meat&paras=3&start-with-lorem=1&format=json');
    }
    
    function getEndpoint2() {
      return axios.get('https://baconipsum.com/api/?type=all-meat&paras=3&start-with-lorem=1&format=json');
    }
    
    axios.all([getEndpoint1(), getEndpont2()])
      .then(axios.spread(function (resp1, resp2) {
        // Both requests are now complete
         console.log(resp1 + resp2)
      }));
    

    【讨论】:

      【解决方案3】:

      尝试查看 Promise.all 方法: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

      this answer 一样,您应该将 XHR 包装在 Promise 中,然后处理所有函数调用的解析。这样就可以按顺序访问端点结果了。

      这是一个有效的小提琴:

      function makeRequest(method, url) {
        return new Promise(function(resolve, reject) {
          var xhr = new XMLHttpRequest();
          xhr.open(method, url);
          xhr.onload = function() {
            if (this.status >= 200 && this.status < 300) {
              resolve(xhr.response);
            } else {
              reject({
                status: this.status,
                statusText: xhr.statusText
              });
            }
          };
          xhr.onerror = function() {
            reject({
              status: this.status,
              statusText: xhr.statusText
            });
          };
          xhr.send();
        });
      }
      
      let url1 = 'https://baconipsum.com/api/?type=all-meat&paras=3&start-with-lorem=1&format=json';
      let url2 = 'https://baconipsum.com/api/?type=all-meat&paras=3&start-with-lorem=1&format=json'
      Promise.all([makeRequest('GET', url1), makeRequest('GET', url2)])
      .then(values => {
        debugger;
        console.log(values);
      });
      

      https://jsfiddle.net/lbrutti/octys8k2/6/

      【讨论】:

        【解决方案4】:

        您必须使用 XMLHttpRequest 吗?如果没有,你最好使用 fetch,因为它返回 Promise,而使用 Promise 会更简单。

        【讨论】:

        • 不,不是,但我是一个非常初学者,我在互联网上寻找解决方案来构建这段代码,这种方式是我唯一完全理解的方式。我知道 fetch 方法,但我仍然知道不够明智地使用它。
        【解决方案5】:

        而不是立即打印它们,将它们保存到局部变量,然后在最后打印它们:

        function endpointsToOneString() {
            let response;          // this line here declares the local variable
            results = 0;           // counts results, successful or not
            const Http = new XMLHttpRequest();
            const url = 'https://baconipsum.com/api/?type=all-meat&paras=3&start-with-lorem=1&format=json';
            Http.open("GET", url);
            Http.send();
        
            Http.onreadystatechange = function () {
                if (this.readyState == 4 && this.status == 200) {
                    response = Http.responseText;   //save one string
                }
                if (this.readyState == 4) {
                    results++;
                }
            }
        
        
            const HttpTwo = new XMLHttpRequest();
            const urlTwo = 'https://baconipsum.com/api/?type=all-meat&paras=3&start-with-lorem=1&format=json';
            HttpTwo.open("GET", urlTwo);
            HttpTwo.send();
        
            HttpTwo.onreadystatechange = function () {
                if (this.readyState == 4 && this.status == 200) {
                    response += HttpTwo.responseText // save the other string
                }
                if (this.readyState == 4) {
                    results++;
                }
            }
        
            while(results < 2) {}  //loops until both requests finish, successful or not
            console.log(response); //print total string
        }
        
        endpointsToOneString();
        

        另外,HttpTwoonreadystatechange 函数调用的是Http.responseText,而不是HttpTwo.responseText。修复该问题以获得最佳效果。

        编辑:感谢 Jhon Pedroza 的提示!

        编辑: Noah B 指出上述内容是肮脏且低效的。他们是完全正确的。更好的版本基于他们的建议,感谢他们:

        function endpointsToOneString() {
            let response1 = '', response2 = ''; // this line declares the local variables
            const Http = new XMLHttpRequest();
            const url = 'https://baconipsum.com/api/?type=all-meat&paras=3&start-with-lorem=1&format=json';
            Http.open("GET", url);
            Http.send();
        
            Http.onreadystatechange = function () {
                if (this.readyState == 4 && this.status == 200) {
                    response1 = Http.responseText;   //save one string
                    checkResults(response1, response2);
                }
            }
        
        
            const HttpTwo = new XMLHttpRequest();
            const urlTwo = 'https://baconipsum.com/api/?type=all-meat&paras=3&start-with-lorem=1&format=json';
            HttpTwo.open("GET", urlTwo);
            HttpTwo.send();
        
            HttpTwo.onreadystatechange = function () {
                if (this.readyState == 4 && this.status == 200) {
                    response2 = HttpTwo.responseText; // save the other string
                    checkResults(response1, response2);
                }
            }
        }
        
        function checkResults(r1, r2) {
            if (r1 != '' && r2 != '') {
                console.log(r1 + r2);
            }
        }
        
        endpointsToOneString();
        

        【讨论】:

        • 如果在执行 console.log 之前请求没有完成,那将不起作用
        • 那是超级低效的。不要循环直到两个响应都完成,而是将每个响应保存到一个单独的变量中,并调用一个函数,如果两个变量都有内容,该函数将打印响应。
        • 检查结果的值一次,在每个回调中,不要有循环!
        【解决方案6】:
        function endpointsToOneString() {
            var response;
            const Http = new XMLHttpRequest();
            const url = 'https://baconipsum.com/api/?type=all-meat&paras=3&start-with-lorem=1&format=json';
            Http.open("GET", url);
            Http.send();
        
            Http.onreadystatechange = function () {
                if (this.readyState == 4 && this.status == 200) {
                    response = this.responseText;
                    HttpTwo.open("GET", urlTwo);
                    HttpTwo.send();
                }
            }
        
        
            const HttpTwo = new XMLHttpRequest();
            const urlTwo = 'https://baconipsum.com/api/?type=all-meat&paras=3&start-with-lorem=1&format=json';
        
            HttpTwo.onreadystatechange = function () {
                if (this.readyState == 4 && this.status == 200) {
                   response += this.responseText; 
                   console.log(response);
                }
            }
        }
        
        endpointsToOneString();
        

        看看这个。只需对您的代码进行最少的编辑。

        【讨论】:

        • 如果 HttpTwo 在 Http 之前完成会怎样?
        • @MaclainAnderson 抓住了你..!如上所述,我们仍然可以避免“承诺”。检查编辑后的代码,应该可以完美运行。
        • 问题是,这些端点是实际的数组 - 请检查那些 url 的...我正在尝试承诺,但它返回给我未定义...jsfiddle.net/up7fm4ob
        • @IzaAdamska 你想要达到什么目的?是否要将这些端点存储在数组中?
        • @IzaAdamska 顺便说一句,对于您发送的小提琴,其中的错误在 ajax 请求中。 onreadystatechange 没有分配正确的函数。尝试传统方式,例如: Http.onreadystatechange = function() { if(this.readyState==4 && this.status == 200) { resolve(this.responseText); } }
        猜你喜欢
        • 2013-02-10
        • 2014-04-12
        • 1970-01-01
        • 1970-01-01
        • 2012-03-11
        • 1970-01-01
        • 2017-08-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多