简体   繁体   English

在 NodeJS (Express) 中使用 Promise.all 找不到集合时的 404 页面

[英]404 page when collection not found with Promise.all in NodeJS (Express)

I use a Promise.all() and ask an URL in multiple Mongo collections.我使用Promise.all()并在多个 Mongo collections 中询问 URL。

I realized that some URLs are missing.我意识到缺少一些 URL。

So I have a 404 page when it's the case.因此,在这种情况下,我有一个 404 页面。 How to avoid that (typically, it's with the Annonce collection)?如何避免这种情况(通常是使用 Annonce 集合)? What can I replace Promise.all with?我可以用什么替换Promise.all

const express = require('express');
const mongoose = require('mongoose');
const { ensureAuthenticated } = require('../helpers/auth');
const router = express.Router();

require('../models/Car');
const Car = mongoose.model('cars');

require('../models/Caratio');
const Caratio = mongoose.model('caratios');

require('../models/User');
const User = mongoose.model('users');

require('../models/Annonce');
const Annonce = mongoose.model('annonces');

router.get('/app/:cars_getroute', ensureAuthenticated, (req, res) => {
    Promise.all([Car.findOne({ cars_getroute: req.params.cars_getroute }),
                Caratio.findOne({ cars_getroute: req.params.cars_getroute }),
                Annonce.findOne({ cars_getroute: req.params.cars_getroute })])
        .then(result => {
            let [cars, caratios, annonces] = result;
}

Promise.all is all or nothing. Promise.all是全部或全部。 It resolves once all promises in the array resolve, or reject as soon as one of them rejects.一旦数组中的所有承诺都解决了,它就会解决,或者一旦其中一个被拒绝,它就会被拒绝。 one alternative way is filtering your promises so that you only wait for resolved ones.另一种方法是过滤您的承诺,以便您只等待已解决的承诺。

Promise.all([p1, p2, p3].map(toResultObject)).then((values) => {
    for (let i = 0; i < values.length; ++i) 
        if (!values[i].success) console.log("ERR: " + values[i].error);
        else console.log(values[i].result);
});

see Avoiding-Promise-all-fail-fast-behavior请参阅避免承诺所有快速失败的行为

NEW ANSWER新答案

router.get('/app/:cars_getroute', ensureAuthenticated, async (req, res) => {
    const promises = [
        Car.findOne({
            cars_getroute: req.params.cars_getroute
        }),
        Caratio.findOne({
            cars_getroute: req.params.cars_getroute
        }),
        Annonce.findOne({
            cars_getroute: req.params.cars_getroute
        })
    ]

    let [cars, caratios, annonces] = await Promise.all(promises.map(p => p.catch(e => null)))
})

But of course you should check each value for nullability.但当然,您应该检查每个值的可空性。

As Rafi said, as soon as a single promise fails in Promise.all , it will be rejected.正如 Rafi 所说,只要 Promise.all 中的单个Promise.all失败,它将被拒绝。

You can replace Promise.all with Promise.allSettled , so that a rejected promise will not impact (or stop) the other promises.您可以将Promise.all替换为Promise.allSettled ,这样被拒绝的 promise 不会影响(或停止)其他承诺。

The Promise.allSettled() method returns a promise that resolves after all of the given promises have either resolved or rejected, with an array of objects that each describes the outcome of each promise. Promise.allSettled() 方法返回一个 promise,它在所有给定的 Promise 都已解决或被拒绝后解决,其中包含一个对象数组,每个对象都描述每个 promise 的结果。

Keep in mind that Promise.allSettled is fairly recent and is not supported by IE or Edge, and older versions of the other browsers.请记住, Promise.allSettled是相当新的,IE 或 Edge 以及其他浏览器的旧版本不支持。
Compatibility table 兼容性表

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM