在某些情况下需要停止多步承诺 [英] Need to stop a mutli-step Promise under certain conditions

查看:41
本文介绍了在某些情况下需要停止多步承诺的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试停止执行多步骤Promise.基本上,在Firebase向我返回一个数字后,如果 snapshot.size === 0 ,则无需继续执行其余操作.我已经尝试过 return ,并且已经尝试过 throw ,但是似乎都无法阻止错误的发生,即:

I am trying to stop a multi-step Promise execution. Basically, after Firebase returns a number to me, if snapshot.size === 0 there is no need to continue with the rest. I've tried return and I've tried throw but neither seem to stop the error from happening which is:

>  error TypeError: snapshot.map is not a function
>      at userSources.get.then.then.snapshot (/Users/username/Personal Projects/ionic-attempt1/functions/index.js:108:14)
>      at process._tickCallback (internal/process/next_tick.js:68:7)
>  (node:18880) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
>      at ServerResponse.setHeader (_http_outgoing.js:470:11)
>      at ServerResponse.header (/Users/username/Personal Projects/ionic-attempt1/functions/node_modules/express/lib/response.js:771:10)
>      at ServerResponse.send (/Users/username/Personal Projects/ionic-attempt1/functions/node_modules/express/lib/response.js:170:12)
>      at ServerResponse.json (/Users/username/Personal Projects/ionic-attempt1/functions/node_modules/express/lib/response.js:267:15)
>      at userSources.get.then.then.then.then.catch.error (/Users/username/Personal Projects/ionic-attempt1/functions/index.js:231:32)
>      at process._tickCallback (internal/process/next_tick.js:68:7)
>  (node:18880) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
>  (node:18880) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
i  functions: Finished "services" in ~1s

现在,第一个错误 TypeError:snapshot.map不是函数实际上在下一个 .then 中,所以我什至不希望发生这种情况.最下面的部分是我不喜欢的,谈论承诺拒绝将如何终止该过程.

Now the first error TypeError: snapshot.map is not a function is actually in the next .then so it's something I don't even want to happen. The bottom part is what I don't like, talking about how promise rejections will terminatee the process.

这是我的代码:

var sources = [];
        var userSources = firestore
            .collection('sources')
            .where('last_queried', '<', oneHourAgo)
            .where('enabled', '==', true)
            .where('uid', '==', uid);
    userSources
        .get()
        .then(snapshot => {
            if (snapshot.size === 0) {
                console.log('fetch: no sources found in the last hour.');
                return response.status(200).json({ message: 'No sources need updating' });
                //throw response.status(200).json({ message: 'No sources need updating' });
            }
            snapshot.forEach(doc => {
                var source = doc.data();

                // update last time checked
                firestore
                    .collection('sources')
                    .doc(doc.id)
                    .set({ last_queried: firebase.firestore.Timestamp.now() }, { merge: true });

                sources.push({
                    id: doc.id,
                    name: source.name,
                    access_token: source.access_token
                });
            });
            return sources;
        })
        .then(snapshot => {
            return Promise.all(
                snapshot.map(source => {

                // Omitting code here

                })
            );
        })
        .then(all_accounts => {
            console.log('all accounts retrieved.');

                // Omitting code here

            return accounts;
        })
        .then(accounts => {

            return response.status(200).json({ message: accountLength + ' accounts updated', accounts: accounts });

        })
        .catch(error => {
            console.log('error', error);
            return response.status(200).json({ message: 'Error: ' + error });
        });

推荐答案

会发生这种情况,它进入这种情况:

what happens is, it enters this case:

    .get()
    .then(snapshot => {
        if (snapshot.size === 0) {
            // the code touchs here, this function returns something that is not an array
            console.log('fetch: no sources found in the last hour.');
            return response.status(200).json({ message: 'No sources need updating' });
            //throw response.status(200).json({ message: 'No sources need updating' });
        }

在下一个.然后打电话给你:

in the next .then call you have this:

.then(snapshot => {
        // snapshot is not an array anymore, and that's causing TypeError: snapshot.map is not a function
        return Promise.all(
            snapshot.map(source => {

            // Omitting code here

            })
        );
    })

您需要的是在第二个.then内更改为这样的功能

What you need is to change to some function like this inside the second .then

.then(snapshot => {
        if (!Array.isArray(snapshot)) {
           // do something here
        }
        return Promise.all(
            snapshot.map(source => {

            // Omitting code here

            })
        );
    })

或者您可以拒绝第一个.then方法调用中的promise链,使用

Or you could reject the promise chain from the first .then method call, using

.then(() => {
    // some code
    return Promise.reject(new Error('fail'))
})

这篇关于在某些情况下需要停止多步承诺的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆