异步函数立即在递归函数中调用then()

时间:2020-10-22 16:37:33

标签: javascript node.js asynchronous async-await

我有一个问题,我尝试使用异步函数进行API调用,但是then()不会等到异步函数返回promise。

异步功能:

async function FgetFloorplansByFolder (idProject,idFolder, data = [], hasMore = false, lastSyncedAt = null) {
  axios.get(API_URL, {
    params:{
      'last_synced_at':lastSyncedAt
    },
      headers: {
        'Authorization': API_TOKEN,
        'Accept': 'application/json'
    }
  })

  .then((response) => {
    let XHasMore = response.headers['x-has-more'];
    let lastSyncedAt = response.headers['x-last-synced-at'];
    for(var i in response.data) {
      if(response.data[i].folder_id != null || response.data[i].folder_id == idFolder){
        data.push(response.data[i])
      }
    }
    if(XHasMore == 'true'){
       FgetFloorplansByFolder(idProject,idFolder, data, XHasMore, lastSyncedAt)
    }
    else {
      console.log(data);
      return data
    }
  })
  .catch((err) => {
    return Promise.reject(err)
  })
}

调用异步函数:

await FgetFloorplansByFolder(req.params.idProject, req.params.idFolder)
.then((result) => {
  console.log(result);
})
.catch((error)=>{
  console.log(error);
})

预期结果是:然后调用中的函数等待,直到getFloorplansByFolders完成其递归调用并在返回打印结果之前返回数据。但是然后打印是不确定的,并且不等到异步函数完成他的调用。

我该怎么办?

1 个答案:

答案 0 :(得分:2)

代码中没有任何内容告诉函数它应该等待那个诺言实现,所以它不会。

通常不要将async / await / .then.catch / .finally混合使用(尽管有例外),请使用其他。

在这种情况下,您可以

  1. 删除async,然后将return放在对axios的调用前面,以返回承诺链;或

  2. 在函数中切换为使用await

(在两种情况下,我强烈敦促您删除将.catch将拒绝转换为实现的undefined处理程序;相反,让调用方看到拒绝,以便他们知道操作失败。)< / p>

#1看起来像这样(注释):

// 1. No `async`
function FgetFloorplansByFolder (idProject,idFolder, data = [], hasMore = false, lastSyncedAt = null) {
  // 2. Return the promise chain
  return axios.get(API_URL, {
    params:{
      'last_synced_at':lastSyncedAt
    },
      headers: {
        'Authorization': API_TOKEN,
        'Accept': 'application/json'
    }
  })

  .then((response) => {
    let XHasMore = response.headers['x-has-more'];
    let lastSyncedAt = response.headers['x-last-synced-at'];
    for(var i in response.data) {
      if(response.data[i].folder_id != null || response.data[i].folder_id == idFolder){
        data.push(response.data[i])
      }
    }
    if(XHasMore == 'true'){
       // 3. Return the promise from the recursive call
       return FgetFloorplansByFolder(idProject,idFolder, data, XHasMore, lastSyncedAt)
    }
    else {
      console.log(data);
      return data
    }
  });
  // 4. Don't put a `.catch` here -- let the caller know the operation failed
}

#2看起来像这样:

async function FgetFloorplansByFolder (idProject,idFolder, data = [], hasMore = false, lastSyncedAt = null) {
  const response = await axios.get(API_URL, {
    params:{
      'last_synced_at':lastSyncedAt
    },
      headers: {
        'Authorization': API_TOKEN,
        'Accept': 'application/json'
    }
  });
  let XHasMore = response.headers['x-has-more'];
  let lastSyncedAt = response.headers['x-last-synced-at'];
  for(var i in response.data) {
    if(response.data[i].folder_id != null || response.data[i].folder_id == idFolder){
      data.push(response.data[i])
    }
  }
  if(XHasMore == 'true'){
     // 3. Return the result of the recursive call
     return FgetFloorplansByFolder(idProject,idFolder, data, XHasMore, lastSyncedAt)
  }
  else {
    console.log(data);
    return data;
  }
}