使用 Async 和 .then 承诺

Posted

技术标签:

【中文标题】使用 Async 和 .then 承诺【英文标题】:Use Async with .then promise 【发布时间】:2019-11-18 07:08:01 【问题描述】:

你好,在设置了一个简单的异步函数后,我想使用 promise return 而不是 try! 但正在回归

await 是保留字

函数中的第二个等待。

我已经尝试将异步返回承诺数据!但也没有用

async infiniteNotification(page = 1) 
    let page = this.state.page;
    console.log("^^^^^", page);
    let auth_token = await AsyncStorage.getItem(AUTH_TOKEN);
    fetch(`/notifications?page=$page`, 
      method: "GET",
      headers: 
        Accept: "application/json",
        "Content-Type": "application/json",
        Access: auth_token
      ,
      params:  page 
    )
      .then(data => data.json())
      .then(data => 

        var allData = this.state.notifications.concat(data.notifications);
        this.setState(
          notifications: allData,
          page: this.state.page + 1,

        );
        let auth_token = await AsyncStorage.getItem(AUTH_TOKEN);
          fetch("/notifications/mark_as_read", 
          method: "POST",
          headers: 
            Accept: "application/json",
            "Content-Type": "application/json",
            Access: auth_token
          ,
          body: JSON.stringify(
            notification: 
              read: true
            
          )
        ).then(response => 
          this.props.changeNotifications();
        );
      )
      .catch(err => 
        console.log(err);
      );
  

> await 是保留字 (100:25) 让 auth_token = 等待 AsyncStorage.getItem(AUTH_TOKEN); ^ fetch("/notifications/mark_as_read",

【问题讨论】:

你的内部函数不是异步的。我会避免使用.then 为什么要混合使用 async await 和 promise.then?这看起来是一个进行一些重构的好地方,使您的请求成为单独的函数,等待那些您可以删除承诺的方法。然后回调 .then(async (data) => 。您可以定义内联异步回调。 这是一个链接,所以这里有更多上下文:) 好的! @JohnRuddell,非常感谢你!并感谢您对重构和代码示例的回答! 【参考方案1】:

您应该重构您提出请求的方式。我将有一个通用函数来处理设置请求和所有内容。

const makeRequest = async (url, options, auth_token) => 
  try 

    // Default options and request method
    if (!options) options = 
    options.method = options.method || 'GET'

    // always pass a body through, handle the payload here
    if (options.body && (options.method === 'POST' || options.method === 'PUT')) 
      options.body = JSON.stringify(options.body)
     else if (options.body) 
      url = appendQueryString(url, options.body)
      delete options.body
    

    // setup headers
    if (!options.headers) options.headers = 
    const headers = new Headers()
    for(const key of Object.keys(options.headers)) 
      headers.append(key, (options.headers as any)[key])
    

    if (auth_token) 
      headers.append('Access', auth_token)
    
    headers.append('Accept', 'application/json')
    headers.append('Content-Type', 'application/json')

    options.headers = headers

    const response = await fetch(url, options as any)
    const json = await response.json()
    if (!response.ok) 
      throw json
    
    return json
   catch (e) 
    console.error(e)
    throw e
  

appendQueryString 是一个小助手,用于在 url 中获取 qs 参数

const appendQueryString = (urlPath, params) => 
  const searchParams = new URLSearchParams()
  for (const key of Object.keys(params)) 
    searchParams.append(key, params[key])
  
  return `$urlPath?$searchParams.toString()`

现在,要了解如何更新代码,您会发现事情变得不那么冗长,而且范围更广。

async infiniteNotification(page = 1) 
  try 
    let auth_token = await AsyncStorage.getItem(AUTH_TOKEN);
    const data = await makeRequest(
      `/notifications`,
       body:  page  ,
      auth_token
    )
    var allData = this.state.notifications.concat(data.notifications);
    this.setState(
      notifications: allData,
      page: this.state.page + 1,
    );
    const markedAsReadResponse = makeRequest(
      "/notifications/mark_as_read",
      
        method: "POST",
        body: 
          notification:  read: true 
        ,
      auth_token
    )
    this.props.changeNotifications();
   catch (e) 
    // TODO handle your errors
  

【讨论】:

/notifications?page=$page 会失败,因为您要根据正文附加查询字符串吗? 是的,或者它只是第二个 qs 参数。可能不会失败,但仍然不应该在那里。我会更新它。不错的收获:)

以上是关于使用 Async 和 .then 承诺的主要内容,如果未能解决你的问题,请参考以下文章

如何在 JS 中使用 try、catch、.then 链接和异步等待来解决承诺?

Async / await vs then 哪个最适合性能?

async/await 在名为“then”的类方法中

NodeJs分页,递归承诺问题

如何编写测试用例来覆盖承诺链中所有嵌套的“then”回调

返回承诺的函数必须是异步的