有条件地使用请求参数进行跳过和限制

Daw*_*n17 0 mongoose mongodb node.js

我已经为我的宁静 API 实现了“限制”和“跳过”查询。

如果我尝试做

'localhost:4000/api/users?skip=60',它将跳过我的数据中的前 60 项

'localhost:4000/api/users?limit=5',只会返回5条数据

然后将这两者结合起来

'localhost:4000/api/users?skip=60&limit=5'将跳过前 60 个数据并且从那一刻起只返回 5 个。

我的跳过和限制实现为:

router.get('/', function(req, res) {

    var skipping = req.query.skip;
    var limiting = req.query.limit;

    // skipping

    if(skipping != null){
        user.find({})
        .skip(3)
        .exec(function(err, users) {
            if(err){
                res.status(404).send({
                    message: err,
                    data: []
                });
            } else {
                res.status(200).send({
                    message: 'OK skipped',
                    data: users
                });
            }
    });
    }

    // limit

    else if(limiting != null){
        user.find({})
        .limit(parseInt(limiting))
        .exec(function(err, users) {
            if(err){
                res.status(404).send({
                    message: err,
                    data: []
                });
            } else {
                res.status(200).send({
                    message: 'OK limited',
                    data: users
                });
            }
    });
    }
  }
});
Run Code Online (Sandbox Code Playgroud)

他们每个人都可以正常工作,但是当我尝试通过将 else if 更改为 if 来组合它们时,应用程序崩溃并显示一条消息

Error: Can't set headers after they are sent.

组合这些查询而不会出错的方法是什么?

Nei*_*unn 5

不要为每个参数更改重写代码。在.skip().limit()改性剂基本上修改“光标”,可以“链接更具体地说,猫鼬他们返回。Query对象,再次你只是‘链’发出之前,.exec()还是真的只是用。‘默认值’:

使用默认值:

router.get('/', function(req, res) {

    var skipping = parseInt(req.query.skip) || 0;
    var limiting = parseInt(req.query.limit) || 0;

    user.find().skip(skipping).limit(limiting).exec(...);

})
Run Code Online (Sandbox Code Playgroud)

或“链接”:

router.get('/', function(req, res) {

    var skipping = req.query.skip;
    var limiting = req.query.limit;

    let query = user.find();

    // Chain skip
    if (skipping != undefined)             // purely since 0 is "falsey"
      query = query.skip(parseInt(skipping));

    // Chain limit
    if (limiting != undefined)
      query = query.limit(parseInt(limiting));

    // Then exec
    query.exec(...);

})
Run Code Online (Sandbox Code Playgroud)

这是“方法链”,您实际上“一直”使用它,只是您没有意识到您正在使用它。例如,没有if条件:

let query = user.find().skip(0).limit(0);
Run Code Online (Sandbox Code Playgroud)

完全相同一样写:

let query = user.find();
query = query.skip(0);
query = query.limit(0);
Run Code Online (Sandbox Code Playgroud)

在第一种形式中,每个“调节剂” find()skip()limit()ALL返回一个Query基于他们被给定了输入的对象上的对象。它们“返回到左侧”,因为它们只是一个function,这就是使您能够“链接”的原因。因此,就实际所做的作业而言,“单独”编写作业是“完全相同的事情”

在任何速率req.params值是存在或undefined不是 null你目前正在尝试做的。因此调用res.send() 两次的错误。

但是您甚至不需要重复发出查询的代码。如图所示,只需使用任一方法“一次”即可