javascript - 使用 Axios 克服 Pending Promise 并在 Node.js 中完成 JSON 构建

标签 javascript node.js json promise axios

我正在尝试构建一个 JSON通过连续制作文件 HTTP requestsAxios :

  1. 获取对象(项目)数组
  2. 在名为任务的每个项目中创建一个数组属性
  3. 获取每个项目的任务
  4. 将每个项目的任务推送到其任务属性中(即在每个项目对象中填充该数组)
  5. 创建 JSON从修改后的项目数组中提取文件

代码:

let getProjects = function() {
  try {
    return axios.get('https://app.asana.com/api/1.0/projects/').then(response => { return response } )
  } catch (error) {
    console.error(error)
  }
}

let getTasks = function(project) {
  try {
    return axios.get('https://app.asana.com/api/1.0/projects/'+project+'/tasks').then(response => { return response } )
  } catch (error) {
    console.error(error)
  }
}

function getAsanaData() {
  return getProjects()
    .then(function(result) {
      let projects = []
      for(let project of result.data.data){
        project.tasks = []
        project.tasks.push(getTasks(project.gid))
        projects.push(project)
      }
      return projects;
    })
}

Promise.try(() => {    
    return getAsanaData();
}).then((result) => {
    console.log(util.inspect(result, {showHidden: false, depth: null}))
    var asanaData = JSON.stringify(result);
    fs.writeFile("thing.json", asanaData);
});

日志结果是这样的:

[ { id: 35534235917762,
    gid: '35534235917762',
    name: 'History+',
    resource_type: 'project',
    tasks: [ Promise { <pending> } ] },
  { id: 35583453238038,
    gid: '35583453238038',
    name: 'NRG - AccountingSeed Phase 2',
    resource_type: 'project',
    tasks: [ Promise { <pending> } ] },
]

注意 Promise { <pending> } 的持久性.

JSON 是这样的:

[
  {
    "id": 35534235917762,
    "gid": "35534235917762",
    "name": "History+",
    "resource_type": "project",
    "tasks": [
      {}
    ]
  },
  {
    "id": 35583453238038,
    "gid": "35583453238038",
    "name": "NRG - AccountingSeed Phase 2",
    "resource_type": "project",
    "tasks": [
      {}
    ]
  }
]

注意空任务属性。

看来我非常接近实现一个完整的 JSON ,但我花了很多时间试图通过未决的 promise最后添加缺失的数据。

我需要做什么?

最佳答案

问题是 getTasks是异步的,所以只需调用 getTasksfor loop 不会等待 Promises 解决。要等待所有这些都解决,请使用 Promise.all在这些 Promise 的数组上,然后当 that 解析时,您可以将结果分配给 project.tasks :

function getAsanaData() {
  return getProjects()
    .then((result) => {
      const projects = result.data.data;
      const taskPromises = projects.map((project) => {
        return getTasks(project.gid)
          .then((task) => {
            project.tasks = [task];
          });
      });
      return Promise.all(taskPromises)
        .then(() => projects);
  });
}

另请注意,一个被拒绝的 Promise不会被困在 try 中/catch block :

try {
  new Promise((_, reject) => setTimeout(reject, 1000))
} catch(e) {
  console.log('error caught');
}

而不是 try/catch , 正确的捕捉方法 Promise错误(当您不使用 await 时)是链接 .catch Promise 末尾的处理程序链:

const getProjects = function() {
  return axios.get('https://app.asana.com/api/1.0/projects/')
    .catch((error) => console.error(error));
}

但是.catch结果为 Promise chain resolving,而不是 rejecting,这意味着当函数被调用时,结果 Promise解析为一个值 ( undefined ) 而不是拒绝,这可能不是您想要的 - 如果您在 caller< 中发现错误,您可能会发现控制流更容易处理/em> 函数的替代:

return Promise.all(taskPromises)
  .then(() => projects);
  .catch((err) => {
    console.log(err);
  });

还有一点需要注意的是 .then比如

.then(response => { return response } )

完全多余 - 现有的 Promise已经解析为 response .链接另一个 Promise进入接收输入并再次输出的末端没有做任何有用的事情 - 随意完全离开它。

关于javascript - 使用 Axios 克服 Pending Promise 并在 Node.js 中完成 JSON 构建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53111667/

相关文章:

android - 获取 : Lorg/apache/http/impl/nio/reactor/DefaultConnectingIOReactor When trying to implement a Unirest API from RapidAPI 的失败分辨率

javascript - 从另一个 JSON 对象开始创建 JSON 对象

javascript - MVC 从下拉列表中过滤 actionResult

node.js - 以太坊错误 : Transaction was not mined within 50 blocks

json - 如何使用 Go map 创建对象的 JSON 数组?

javascript - 通过异步回调函数传递不同版本的变量

javascript - Nodejs mysql 异步/等待函数

javascript - 在翻转时切换父元素的类

JavaScript 符号 : (function() { . .. } )();

javascript - 如何从 Angular 9 正确加载和使用gapi.iframes库?