从 Axios API 返回数据

Posted

技术标签:

【中文标题】从 Axios API 返回数据【英文标题】:Returning data from Axios API 【发布时间】:2018-08-05 10:19:06 【问题描述】:

我正在尝试使用 Node.JS 应用程序来发出和接收 API 请求。它使用 Axios 向另一台服务器发出 get 请求,其中包含从 API 调用接收到的数据。第二个 sn-p 是脚本从调用中返回数据的时候。它实际上会将数据写入控制台,但不会在第二个 API 中将其发送回。

function axiosTest() 
    axios.get(url)
        .then(function (response) 
            console.log(response.data);
            // I need this data here ^^
            return response.data;
        )
        .catch(function (error) 
            console.log(error);
        );

...

axiosTestResult = axiosTest(); 
response.json(message: "Request received!", data: axiosTestResult);

我知道这是错误的,我只是想找到一种方法让它发挥作用。我似乎可以从中获取数据的唯一方法是通过 console.log,这对我的情况没有帮助。

【问题讨论】:

How do I return the response from an asynchronous call?的可能重复 我觉得人们在这个问题上走得太远了。基本上,您在 axiosTest 函数中缺少返回,并且您没有等待它的结果。使用 Promises 时,始终返回 Promise 并在需要结果时等待它 【参考方案1】:

问题是原来的axiosTest() 函数没有返回承诺。为了清楚起见,这里有一个扩展的解释:

function axiosTest() 
    // create a promise for the axios request
    const promise = axios.get(url)

    // using .then, create a new promise which extracts the data
    const dataPromise = promise.then((response) => response.data)

    // return it
    return dataPromise


// now we can use that data from the outside!
axiosTest()
    .then(data => 
        response.json( message: 'Request received!', data )
    )
    .catch(err => console.log(err))

函数可以写得更简洁:

function axiosTest() 
    return axios.get(url).then(response => response.data)

或者使用异步/等待:

async function axiosTest() 
    const response = await axios.get(url)
    return response.data

Guide on using promises Info on async functions

【讨论】:

如果函数 axiosTest() 位于与调用函数不同的文件中,我似乎无法使其工作: axiosTest().then.... 在这种情况下有什么特别要做的吗? 对我来说也一样,我想将 axiosTest() 函数放在与调用函数不同的文件中。有人对此有想法吗? 听起来您只是在问如何将代码拆分为单独的文件。研究通过 javascript 使用模块 你是真正的 MVP @kingdaro 我多年来一直坚持使用我的代码,然后我找到了你的答案,多么传奇 在 axios.post() 之前使用 await 对我有用【参考方案2】:

我知道这篇文章已经过时了。但是我已经看到有人尝试使用 async 和 await 来回答但弄错了。这应该为任何新的引用清除它

async function axiosTest() 
      try 
        const data:response = await axios.get(url) //use data destructuring to get data from the promise object
        return response
      

      catch (error) 
        console.log(error);
      
    

【讨论】:

这是正确的答案 - 当您在应用程序中调试代码时,调用上述函数的函数将与链中的所有其他函数一样返回,但稍后代码将返回在等待之后开始执行。您需要使应用程序中的所有函数异步,并使用 await 调用所有函数。在 return 语句上放一个断点,在调用者的下一行代码上放一个断点——一切都会变得清晰。【参考方案3】:

您可以使用简单的回调函数填充所需的数据, 假设我们要填充一个名为lst 的列表, 我们有一个 pupulates 列表的函数,

const lst = [];  
const populateData = (data) => lst.push(data) 

现在我们可以将回调函数传递给正在进行 axios 调用的函数,当我们从响应中获取数据时,我们可以填充列表。

现在我们创建发出请求的函数并将populateData 作为回调函数传递。

function axiosTest (populateData) 
        axios.get(url)
       .then(function(response)
               populateData(response.data);
        )
        .catch(function(error)
               console.log(error);
         );
   

【讨论】:

感谢@Fahad_Shovon!这花了我一天的时间进行故障排除,我使用您的解决方案解决了这个问题 伙计们,你讨厌看到它发生。【参考方案4】:

axiosTest() 正在触发 asynchronously 并且没有被等待。

之后需要连接then() function 以捕获response variable (axiosTestData)。

请参阅Promise 了解更多信息。

查看Async升级。

// Dummy Url.
const url = 'https://jsonplaceholder.typicode.com/posts/1'

// Axios Test.
const axiosTest = axios.get

// Axios Test Data.
axiosTest(url).then(function(axiosTestResult) 
  console.log('response.JSON:', 
    message: 'Request received',
    data: axiosTestResult.data
  )
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.js"></script>

【讨论】:

【参考方案5】:

axios 库创建一个 Promise() 对象。 Promise 是 JavaScript ES6 中的内置对象。当使用 new 关键字实例化此对象时,它需要一个函数作为参数。这个单一的函数又接受两个参数,每个参数也是函数——resolve和reject。

Promises 执行客户端代码,并且由于 cool Javascript 异步流程,最终可以解决一两件事,即解决方案(通常认为在语义上等同于 Promise 的成功),或者该拒绝(被广泛认为是错误的解决方案)。例如,我们可以持有对某个 Promise 对象的引用,该对象包含一个最终返回响应对象(将包含在 Promise 对象中)的函数。因此,我们可以使用这样的 Promise 的一种方法是等待 Promise 解析为某种响应

您可能会提出我们不想等待几秒钟左右让我们的 API 返回调用!我们希望我们的 UI 能够等待 API 响应时做一些事情。否则,我们将拥有一个非常缓慢的用户界面。那么我们如何处理这个问题呢?

Promise 是异步的。在负责执行 Javascript 代码的引擎(例如 Node 或普通浏览器)的标准实现中,它将在另一个进程中解析,而我们事先不知道 promise 的结果是什么。通常的策略是然后发送我们的函数(即一个类的 React setState 函数)到 Promise,根据某种条件(取决于我们选择的库)来解决。这将导致我们的本地 Javascript 对象根据 Promise 解析进行更新。因此,您可以考虑可能发送到异步方法的函数,而不是 getter 和 setter(在传统 OOP 中)。

我将在此示例中使用 Fetch,以便您可以尝试了解 Promise 中发生了什么,看看您是否可以在您的 axios 代码中复制我的想法。 Fetch 与 axios 基本相似,没有先天的 JSON 转换,并且具有不同的 promise 解析流程(您应该参考 axios 文档来学习)。

GetCache.js

const base_endpoint = BaseEndpoint + "cache/";
// Default function is going to take a selection, date, and a callback to execute.
// We're going to call the base endpoint and selection string passed to the original function.
// This will make our endpoint.
export default (selection, date, callback) =>   
  fetch(base_endpoint + selection + "/" + date) 
     // If the response is not within a 500 (according to Fetch docs) our promise object
     // will _eventually_ resolve to a response. 
    .then(res => 
      // Lets check the status of the response to make sure it's good.
      if (res.status >= 400 && res.status < 600) 
        throw new Error("Bad response");
      
      // Let's also check the headers to make sure that the server "reckons" its serving 
      //up json
      if (!res.headers.get("content-type").includes("application/json")) 
        throw new TypeError("Response not JSON");
      
      return res.json();
    )
    // Fulfilling these conditions lets return the data. But how do we get it out of the promise? 
    .then(data => 
      // Using the function we passed to our original function silly! Since we've error 
      // handled above, we're ready to pass the response data as a callback.
      callback(data);
    )
    // Fetch's promise will throw an error by default if the webserver returns a 500 
    // response (as notified by the response code in the HTTP header). 
    .catch(err => console.error(err));
;

现在我们已经编写了 GetCache 方法,让我们看看更新 React 组件状态的例子......

一些 React Component.jsx

// Make sure you import GetCache from GetCache.js!

resolveData() 
    const  mySelection, date  = this.state; // We could also use props or pass to the function to acquire our selection and date.
    const setData = data => 
      this.setState(
        data: data,
        loading: false 
        // We could set loading to true and display a wee spinner 
        // while waiting for our response data, 
        // or rely on the local state of data being null.
      );
    ;
  GetCache("mySelelection", date, setData);
  

最终,您不会像这样“返回”数据,我的意思是您可以,但改变您的思维方式更为惯用......现在我们正在发送数据到异步方法。

编码愉快!

【讨论】:

【参考方案6】:

IMO 对您的客户端 js 代码极为重要的经验法则是将数据处理和 ui 构建逻辑分离到不同的函数中,这对于 axios 数据获取也有效......这样您的控制流和错误处理将更加简单和易于管理,从这里可以看出 ok fetch

还有这个 NOK fetch

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script>

       function getUrlParams ()
          var url_params = new URLSearchParams();
          if( window.location.toString().indexOf("?") != -1) 
             var href_part = window.location.search.split('?')[1]
             href_part.replace(/([^=&]+)=([^&]*)/g,
                function(m, key, value) 
                   var attr = decodeURIComponent(key)
                   var val = decodeURIComponent(value)
                   url_params.append(attr,val);
             );
          
          // for(var pair of url_params.entries())  consolas.log(pair[0]+ '->'+ pair[1]); 
          return url_params ;
       


      function getServerData (url, urlParams )
          if ( typeof url_params == "undefined" )  urlParams = getUrlParams()  
          return axios.get(url ,  params: urlParams  )
          .then(response => 
             return response ;
          )
          .catch(function(error) 
             console.error ( error )
             return error.response;
          )
       

    // Action !!!
    getServerData(url , url_params)
        .then( response => 
           if ( response.status === 204 ) 
              var warningMsg = response.statusText
              console.warn ( warningMsg )
              return
            else if ( response.status === 404 || response.status === 400) 
              var errorMsg = response.statusText // + ": "  + response.data.msg // this is my api
              console.error( errorMsg )
              return ;
            else 
              var data = response.data
              var dataType = (typeof data)
              if ( dataType === 'undefined' ) 
                 var msg = 'unexpected error occurred while fetching data !!!'
                 // pass here to the ui change method the msg aka
                 // showMyMsg ( msg , "error")
               else 
                 var items = data.dat // obs this is my api aka "dat" attribute - that is whatever happens to be your json key to get the data from
                 // call here the ui building method
                 // BuildList ( items )
              
              return
           

        )




    </script>

【讨论】:

【参考方案7】:

你可以使用异步 - 等待:

async function axiosTest() 
  const response = await axios.get(url);
  const data = await response.json();  

【讨论】:

你好!这不能回答 OP 的问题。他想返回数据。此外,您将通过.json() 调用放置结果数据,这在使用fetch 时是必需的,但在Axios 中不存在(也不需要)。请记住提供解释,而不仅仅是代码的 sn-p。请在***.com/help/how-to-answer查看“回答问题”【参考方案8】:

试试这个,

function axiosTest() 
    axios.get(url)
        .then(response => response.data)
        .catch(error => error);


async function getResponse () 
        const response = await axiosTest();
        console.log(response);


getResponse()

它可以工作,但是您要获取响应的每个函数都需要是异步函数或使用额外的.then() 回调。

function axiosTest() 
    axios.get(url)
        .then(response => response.data)
        .catch(error => error);


async function getResponse () 
        axiosTest().then(response => 
                console.log(response)
        );


getResponse()

如果有人知道避免这种情况的方法,请告诉。

还可以查看 Katsiaryna (Kate) Lupachova 的 article on Dev.to。我认为这会有所帮助。

【讨论】:

【参考方案9】:
    async handleResponse()
      const result = await this.axiosTest();
    

    async axiosTest () 
    return await axios.get(url)
    .then(function (response) 
            console.log(response.data);
            return response.data;)
.catch(function (error) 
    console.log(error);
);

您可以在本文的 GET 部分找到检查 https://flaviocopes.com/axios/#post-requests url 并找到一些相关信息。

【讨论】:

以上是关于从 Axios API 返回数据的主要内容,如果未能解决你的问题,请参考以下文章

当 API 返回空数据时显示警告(Vue.js / Axios)

从 axios 的响应头中获取数据

Axios调用api,但不返回数据给客户端。

axios GET 请求不返回任何数据(VueJS 和 NodeJS)

使用 axios 获取数据后 React useEffect 返回空数组

无法使用 api 从 axios 获取数据 - vue js