Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/453.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用bluebird在顺序流中管理异步操作_Javascript_Promise_Bluebird - Fatal编程技术网

Javascript 使用bluebird在顺序流中管理异步操作

Javascript 使用bluebird在顺序流中管理异步操作,javascript,promise,bluebird,Javascript,Promise,Bluebird,首先,我不想否认我对承诺非常陌生,并且试图在我的新Node.js应用程序中更好地管理承诺。我使用蓝鸟是基于我从朋友和社区听到的。下面是一个场景: 该应用程序有一个注册流,这是一个典型的用例,在该用例中,必须发生以下事件才能注册新用户: 检查用户是否已经存在 如果没有,请添加新用户 发送验证电子邮件 我有3个单独的函数来处理上述每个步骤 下面是我使用Promissions flow提出的建议……但不知何故,我不相信下面的代码: user.isExistingUser(email)

首先,我不想否认我对承诺非常陌生,并且试图在我的新Node.js应用程序中更好地管理承诺。我使用蓝鸟是基于我从朋友和社区听到的。下面是一个场景:

该应用程序有一个注册流,这是一个典型的用例,在该用例中,必须发生以下事件才能注册新用户:

  • 检查用户是否已经存在
  • 如果没有,请添加新用户
  • 发送验证电子邮件 我有3个单独的函数来处理上述每个步骤

    下面是我使用Promissions flow提出的建议……但不知何故,我不相信下面的代码:

    user.isExistingUser(email)
            .then((successData) => {
                if(successData && successData.length === 0) {
                    user.signUp(signUpInfo)
                    .then((successData) => {
                        emailService.sendVerificationEmail(recipientInfo)
                        .then((successData) => {
                         res.json(responseUtility.getApiResponse(successData));
                        })
                        .catch((errorObj) => {
                            res.json(responseUtility.getApiResponse(null, null, errorObj));
                        });
                    })
                    .catch((errorObj) => {
                        res.json(responseUtility.getApiResponse(null, null, errorObj));
                    });
                } else {
                    res.json(responseUtility.getApiResponse(null, [{
                        param: 'email',
                        msg: 'An account already exists with this email'
                    }], null));
                }
            })
            .catch((errorObj) => {
                res.json(responseUtility.getApiResponse(null, null, errorObj));
            });
    

    正如您可能看到的,代码似乎有点太长,可能会变得有点难以跟踪。这里的一些蓝鸟专家能提供更好或更可读的代码吗?

    你应该更好地利用链接。始终
    return
    从异步执行操作的函数中获得承诺

    user.isExistingUser(email).then(successData => {
        if (successData && successData.length === 0) {
            return user.signUp(signUpInfo).then(() => {
    //      ^^^^^^
                return emailService.sendVerificationEmail(recipientInfo);
    //          ^^^^^^
            }).then(successData => {
                res.json(responseUtility.getApiResponse(successData));
            });
        } else {
            res.json(responseUtility.getApiResponse(null, [{
                param: 'email',
                msg: 'An account already exists with this email'
            }], null));
        }
    }).catch(errorObj => {
        res.json(responseUtility.getApiResponse(null, null, errorObj));
    });
    

    你应该更好地利用链接。始终
    return
    从异步执行操作的函数中获得承诺

    user.isExistingUser(email).then(successData => {
        if (successData && successData.length === 0) {
            return user.signUp(signUpInfo).then(() => {
    //      ^^^^^^
                return emailService.sendVerificationEmail(recipientInfo);
    //          ^^^^^^
            }).then(successData => {
                res.json(responseUtility.getApiResponse(successData));
            });
        } else {
            res.json(responseUtility.getApiResponse(null, [{
                param: 'email',
                msg: 'An account already exists with this email'
            }], null));
        }
    }).catch(errorObj => {
        res.json(responseUtility.getApiResponse(null, null, errorObj));
    });
    

    我想实现相同代码的一种合理方法可能是:

    user.isExistingUser(email)
        .then(successData => successData &&
                             successData.length === 0 ? user.signUp(signUpInfo)
                                                            .then(successData => emailService.sendVerificationEmail(recipientInfo))
                                                            .then(successData => res.json(responseUtility.getApiResponse(successData)))
                                                      :  res.json(responseUtility.getApiResponse(null, [{param: 'email', msg: 'An account already exists with this email'}], null)))
        .catch(err => res.json(responseUtility.getApiResponse(null, null, err)));
    

    我想实现相同代码的一种合理方法可能是:

    user.isExistingUser(email)
        .then(successData => successData &&
                             successData.length === 0 ? user.signUp(signUpInfo)
                                                            .then(successData => emailService.sendVerificationEmail(recipientInfo))
                                                            .then(successData => res.json(responseUtility.getApiResponse(successData)))
                                                      :  res.json(responseUtility.getApiResponse(null, [{param: 'email', msg: 'An account already exists with this email'}], null)))
        .catch(err => res.json(responseUtility.getApiResponse(null, null, err)));
    

    不理解您的代码有什么问题

    基本上,您的代码是嵌套回调。典型的嵌套回调如下所示:

    funcation(args.., 
        function(args..., 
            function(args){...}
        ){...}
    ){...}
    
    你的答案是:

    function(args).then(()=> {
       function(args).then(() => {
           function(args){...}
       })
    })
    
    差别不大,不是吗


    这是使用承诺的正确方式。

    解决你的问题的关键是兑现承诺。这实际上是承诺的全部要点

    基本上,您希望您的
    然后
    回调返回一个承诺。通过这种方式,您可以链接您的承诺,以避免代码的嵌套回调样式

    每个
    。然后
    方法本身总是返回一个承诺

    promiseB = promiseA.then(()=> {
        // callback 
        return promiseC
    });
    
    如果
    callback
    返回像上面这样的承诺,您可以有效地想到
    promiseB=promiseC
    。现在,如果我们有

    promiseC = promiseA.then(()=> {
        // callback 
        return promiseB
    });
    promiseE = promiseC.then(()=> {
        // callback 
        return promiseD
    });
    
    您可以将它们链接在一起。然后,可以将上述内容缩短为:

    promiseA.then(()=> {
        // callback 
        return promiseB
    }).then(()=> {
        // callback 
        return promiseD
    });
    

    直接回答您的问题。

    让userPromise=user.isExistingUser(电子邮件);
    //处理新用户
    用户承诺
    .然后((用户数据)=>{
    断言userData.length==0;
    //报名
    //假设user.signUp是一个承诺,recipientInfo是其解析值
    返回user.signUp(userData.signUpInfo);
    })
    .然后((recipientInfo)=>{
    //发送验证电子邮件
    //假设user.sentVerificationEmail是一个承诺,其解析值为emailSuccessData
    返回user.sentVerificationEmail(recipientInfo)
    })
    。然后((emailSuccessData)=>{
    res.json(responseutability.getApiResponse(emailSuccessData));
    })
    //如果先前的任何承诺被拒绝,
    //接下来的。然后将被有效地绕过并落在这个陷阱中
    .catch((错误)=>{
    res.json(responseutability.getApiResponse(null,null,err));
    })
    //处理现有用户
    userPromise.then((successData)=>{
    assert successData.length>0
    常量json=[{
    参数:“电子邮件”,
    msg:'此电子邮件已存在一个帐户'
    }]
    res.json(responseutability.getApiResponse(null,json,null));
    }); 
    
    //不用再抓了。如果userPromise被拒绝,它将由上面的catch处理。
    不理解您的代码有什么问题。

    基本上,您的代码是嵌套回调。典型的嵌套回调如下所示:

    funcation(args.., 
        function(args..., 
            function(args){...}
        ){...}
    ){...}
    
    你的答案是:

    function(args).then(()=> {
       function(args).then(() => {
           function(args){...}
       })
    })
    
    差别不大,不是吗


    这是使用承诺的正确方式。

    解决你的问题的关键是兑现承诺。这实际上是承诺的全部要点

    基本上,您希望您的
    然后
    回调返回一个承诺。通过这种方式,您可以链接您的承诺,以避免代码的嵌套回调样式

    每个
    。然后
    方法本身总是返回一个承诺

    promiseB = promiseA.then(()=> {
        // callback 
        return promiseC
    });
    
    如果
    callback
    返回像上面这样的承诺,您可以有效地想到
    promiseB=promiseC
    。现在,如果我们有

    promiseC = promiseA.then(()=> {
        // callback 
        return promiseB
    });
    promiseE = promiseC.then(()=> {
        // callback 
        return promiseD
    });
    
    您可以将它们链接在一起。然后,可以将上述内容缩短为:

    promiseA.then(()=> {
        // callback 
        return promiseB
    }).then(()=> {
        // callback 
        return promiseD
    });
    

    直接回答您的问题。

    让userPromise=user.isExistingUser(电子邮件);
    //处理新用户
    用户承诺
    .然后((用户数据)=>{
    断言userData.length==0;
    //报名
    //假设user.signUp是一个承诺,recipientInfo是其解析值
    返回user.signUp(userData.signUpInfo);
    })
    .然后((recipientInfo)=>{
    //发送验证电子邮件
    //假设user.sentVerificationEmail是一个承诺,其解析值为emailSuccessData
    返回user.sentVerificationEmail(recipientInfo)
    })
    。然后((emailSuccessData)=>{
    res.json(responseutability.getApiResponse(emailSuccessData));
    })
    //如果先前的任何承诺被拒绝,
    //接下来的。然后将被有效地绕过并落在这个陷阱中
    .catch((错误)=>{
    res.json(responseutability.getApiResponse(null,null,err));
    })
    //处理现有用户
    userPromise.then((successData)=>{
    assert successData.length>0
    常量json=[{
    参数:“电子邮件”,
    msg:'此电子邮件已存在一个帐户'
    }]
    res.json(responseutability.getApiResponse(null,json,null));
    }); 
    
    //不用再抓了。如果userPromise被拒绝,它将由上面的catch处理。
    doeshelp@JaromandaX感谢您的快速回复…我想知道如果电子邮件验证步骤失败会发生什么…是否可以捕获任何错误。最后捕获块?另外,我想知道我是否可以在bluebird中使用.mapseries api?是的,单个catchblock可以捕获任何拒绝-我不知道bluebird promise sugar,我只使用本机承诺—尽管Bluebird具有明显的性能优势—但我不确定在这种情况下为什么要使用它,因为您需要从
    .then()
    处理程序中返回所有嵌套承诺