按顺序执行 mongoose 查询,return 首先找到成功的查询

Execute mongoose queries in order and return first that found something successfully

    StopsModel.findOne({stop_lat: stations[0]}).exec()
.then(function(stop){
    if (stop) res.json(stop);
    else {
        StopsModel.findOne({stop_lat: stations[1]}).exec()
        .then(function(stop){
            if (stop) res.json(stop);
            else {
                StopsModel.findOne({stop_lat: stations[2]}).exec()
                .then(function(stop){
                    if (stop) res.json(stop);
                    else {
                        StopsModel.findOne({stop_lat: stations[3]}).exec()
                        .then(function(stop){
                            if (stop) res.json(stop);
                        })
                    }
                })
            }
        })
    }
})

我正在使用 mongoose 和 bluebird,我在这里要做的是按顺序遍历纬度数组,然后使用存在于数组中的第一个纬度将响应发送回前端数据库,不是 returns 成功的第一个查询。

我知道 bluebird 有很多 promise 解析技术,比如 .any .all .some .settle,但我不知道使用哪一个与上面的代码效果相同。

您可以简单地使用 $in 运算符获取所有内容,然后从返回的数组中选择一个。这也意味着只有一个数据库查询而不是 4 个。

StopsModel.find({stop_lat: {$in: stations}}, function(err, stops){
    if(!err && stops.length) {
        return res.json(stops[0]);
        // to get random stop use
        // return res.json(stops[Math.random(0, stops.length - 1)]);
    }
    res.json([]);
});

@Molda 的回答看起来可能是可行的方法,但为了记录,问题中的代码可以通过构建 .catch() 链来机械化为任意长度的 stations 数组如下:

stations.reduce(function(promise, station) {
    return promise.catch(function() {
        return StopsModel.findOne({'stop_lat': station}).exec().then(function(stop) {
            if(stop) {
                return stop; // success!! break out of the catch chain
            } else {
                throw new Error(); // continue down the catch chain
            }
        });
    });
}, Promise.reject()).then(function(stop) {
    res.json(stop);
}, function(error) {
    // no matching stop was found.
    // do something with the error.
});

只要抛出错误,链就会继续另一个 .findOne().exec() 请求。

尽管效率相对较低,但这样做实际上可能有一个优势,即任何不良 station 不太可能破坏整个企业。除了故意抛出的错误外,任何 .findOne().exec() 错误也将被捕获,链将继续。