快速响应,具有递归功能

如何解决快速响应,具有递归功能

我正试图从Cloudinary中获取所有照片,但是每次调用限制为500个元素。

呼叫中存在一个名为next_cursor的属性,您可以将其用作分页。

我以递归方式进行操作,但是当我尝试在Express中发送响应超出范围时,关于如何使用递归函数的结果进行响应的任何想法?

谢谢!

const express = require("express");
const router = express.Router();
const cloudinary = require("cloudinary").v2;

const { cloudinarySettings } = require("../config/cloudinary_config");

router.get("/statistics",async (req,res) => {
    function list_resources(results,next_cursor = null) {
        cloudinary.api.resources(
            {
                resource_type: "image",mex_results: 500,next_cursor: next_cursor,},function (err,res) {
                console.log(err);
                res.resources.forEach(function (resource) {
                    results.push(resource);
                });

                if (res.next_cursor) {
                    list_resources(results,res.next_cursor);
                } else {
                    return res.status(200).json(results)
                }
            }
        );
    }

    const results = [];
    list_resources(results);
});

解决方法

您将需要修改list_resources函数以按如下方式返回promise,然后使用async-await等待结果,然后再提交res

router.get("/statistics",async (req,res) => {
    async function list_resources(results,next_cursor = null) {
        await new Promise((resolve) => {
            cloudinary.api.resources(
                {
                    resource_type: "image",mex_results: 500,next_cursor: next_cursor,},function (err,res) {
                    if (err) {
                        console.log(err);
                        resolve();
                        
                    } else {
                        res.resources.forEach(function (resource) {
                            results.push(resource);
                        });

                        if (res.next_cursor) {
                            list_resources(results,res.next_cursor).then(() => resolve());
                        } else {
                            resolve();
                        }
                    }
                    
                }
            );
        });
    }

    const results = [];
    await list_resources(results);
    return res.status(200).json(results);
});
,

我可能会以不同的方式分解问题,并制作一个更简单的递归函数来返回结果,而不是修改传入的数组。为了保持整洁,我还将函数移出router.get回调。 / p>

所以它可能看起来像这样:

const listResources = async ({resource_type,max_results = 500,next_cursor = null} = {}) => {
  return new Promise((resolve,reject) => {
    cloudinary .api .resources (
      {resource_type,max_results,next_cursor},async (err,{resources,next_cursor}) => {
        try {
          if (err) {reject (err)}
          else resolve ([
            ...resources,...(next_cursor ? await listResources ({resource_type,next_cursor}) : [])
          ])
        } catch (err) {reject (err)}
      }
    )
  })
}

router.get('/statistics',res) => {
  try {
    const results = await listResources ({resource_type: 'image'})
    res .status (200) .json (results)
  } catch (err) {
    console .warn (err)
    res .status (404) // or 500,or whatever,based on error
  }
})

最有趣的部分是:

    resolve ([
      ...resources,next_cursor}) : [])
    ])

如果返回一个next_cursor值,则在解析之前,将使用它的递归调用结果附加到当前结果中。如果没有得到,则附加一个空数组。

很高兴能够编写这个可以说更简单的cloudinary回调函数:

    async (err,next_cursor}) => err 
      ? reject (err)
      : resolve ([
          ...resources,next_cursor}) : [])
        ])

避免使用try-catchif-else块。但是我找不到一种简单的方法来将错误传递回最初调用listResources的函数。

您可以在浏览器中使用此代码段中cloudinaryrouter的虚拟实现对此进行测试:

const listResources = async ({resource_type,next_cursor = null}) => {
  return new Promise((resolve,reject) => {
    cloudinary.api.resources(
      {resource_type,res) => {
  try {
    const results = await listResources ({resource_type: 'image',max_results: 3})
    res .status (200) .json (results)
  } catch (err) {
    console .warn (err)
    res .status (500) // or whatever,based on error
  }
})
.as-console-wrapper {max-height: 100% !important; top: 0}
<script>
// Dummy implementations for testing:

const cloudinary = (() => {
  const vals = [{t: 'image',id: 1,v: 'a'},{t: 'image',id: 2,v: 'b'},id: 3,v: 'c'},{t: 'pdf',id: 4,v: 'd'},id: 5,v: 'e'},id: 6,v: 'f'},{t: 'video',id: 7,v: 'g'},id: 8,v: 'h'},id: 9,v: 'i'},id: 10,v: 'j'},id: 11,v: 'k'},id: 12,v: 'l'}]; 
  const last = (xs) => xs.length ? xs[xs.length - 1] : undefined; 
  return {api: {
    resources: ({resource_type,next_cursor = 0},fn) => {
      const res = vals .filter (({t,id}) => t == resource_type && id > next_cursor).slice(0,max_results)
//      fn (next_cursor == 3 ? 'houston,we have a problem' : null,{  // *** use to test an error condition ***
      fn (null,{
        resources: res,...(res.length > 0 && last(res).id < last(vals).id ? {next_cursor: last(res).id} : {})
      })
    }
  }}
})()

const router = {
  get: (path,fn) =>
    fn (
      {},{status: (n) => {
        console.log(`returning ${n} for request to ${path}`)
        return {
          json: val => console.log(`Body: \n${JSON.stringify(val,null,4)}`)
        }
      }}
    )
}
</script>

如果您取消注释虚拟虚拟代码中的替代行并注释了上一行,则可以看到cloudinary .api .resources引发错误时的行为。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-