0

我很难理解 Promise 是如何工作的。在基础上,我了解什么和resolve是。reject.catch ()

但是,我正在尝试创建一个 Promise 函数(使用Bluebird),该函数本身使用另一个 Promise 函数,并且我想从这个嵌套的 Promise 函数返回解析或拒绝。所以我做了以下事情:

FacebookMes​​sengerAPI.js

const request = require("request-promise");
const Prom = require("bluebird");

exports.send = (sender_psid, response) => {

    return Prom.try(() => {
        if (sender_psid == null || sender_psid == undefined || sender_psid == "") {
            console.error("Invalid sender_psid: \t" + sender_psid);
            let error = {
                code : errorCodes.ERR_INVALID_PARAMETER,
                message : "Invalid sender_psid value"
            }
            return Prom.reject(error); // This works fine
        }

        if (response == null || response == undefined) {
            console.error("Response body is either null or undefined:\t" + response);
            let error = {
                code : errorCodes.ERR_INVALID_PARAMETER,
                message : "Response is either null or undefined"
            }
            return Prom.reject(error); // This also works fine
        }

        let options = {
            url : appConstants.URL_FACEBOOK_GRAPH_API,
            qs : { access_token : appConstants.TOKEN_PAGE_ACCESS },
            method : "POST",
            body : response,
            json : true
        };

        request(options)
            .then((responseBody) => {
                console.log("ResponseBody: \t" + responseBody);
            }, (rejected) => {
                if (rejected.error.error.message) {
                    let error = {
                        code : errorCodes.ERR_FB_GRAPH_API,
                        message : rejected.error.error.message
                    }
                    throw error; // This is where things go wrong
                }
                
            })
            .catch((err) => {
                console.error("Error while calling FB Graph API:\n" + err);
                let error = {
                    code : errorCodes.ERR_UNMAPPED_ERROR,
                    message : err
                };
            });
    });

}

TestApp.js——调用这个 API 的人

"use strict";

const facebookMessengerApi = require("./service/FacebookMessengerApi");

facebookMessengerApi.send(1111,1111).then((resolved) => {
    if (resolved) {
        console.log("Resolves ==> ",resolved);
    }
}, (rejected) => {
    if (rejected) {
        console.log("Rejected:\t" + someshit);
        throw new Error("An err thrown here")
    }
}).catch((error) => {
    console.error("ERRORIFIED:\n\n" + error);
});

这里的问题是,我不知道如何将 Promise 对象从request本身是 Promise 函数并嵌套在父 Promise 函数中的函数发送到父 Promise 函数。

关于请求功能的解决/拒绝:

  1. 当我抛出错误时throw new error,它被捕获在函数的立即.catch块中request。它永远不会交给这个 API 的实际调用者

  2. 当我使用 时Prom.reject(error),我会收到unhandled rejection警告,尽管我不知道我没有在哪里处理它,因为我已经在request方法和这个 API 的调用者中处理了它。除此之外,Prom.reject(error)实际上最终出现在函数的.catch()块中,request而不是调用者函数的块中。

4

1 回答 1

1

笔记:

  • 根据定义,您正在拒绝拒绝,这是 Promise 失败(即另一个拒绝
  • 当你.catch()在 Promise 链上执行 a 时,它会恢复链
    • 这意味着在 catch 之后,.then()当前链或父链中的下一个现在将获取从 catch 语句返回的任何内容。
    • 因此,您应该:
      • 在最后运行 catch ,因此之后不再进行任何处理
      • 和/或通过再次抛出/拒绝来触发异常,直到触发下一个 catch 语句
  • 根据返回的内容,Promise 的行为会有所不同:
    • <Promise>:等到完成,.then()在链中的下一个使用值
    • Not a promise: 使用返回值作为下一个的输入.then()
    • <Exception>: 不是真正的返回,而是会导致它转到下一个catch(e)e异常信息在哪里
    • <Rejection>:来自有拒绝的子链,或Promise.reject(e)作为返回值。继续下一个.catch(e)

TL;DR -.then /的输出.catch将始终是下一个的输出,.then()除非其中有异常或拒绝。在这种情况下,.catch()将触发下一个

解决方案/重构

// Using standard promises
const prBody = _ => {
    if (sender_psid == null || sender_psid == undefined || sender_psid == "") {
        console.error("Invalid sender_psid: \t" + sender_psid);
        let error = {
            code : errorCodes.ERR_INVALID_PARAMETER,
            message : "Invalid sender_psid value"
        }
        throw error
    }

    if (response == null || response == undefined) {
        console.error("Response body is either null or undefined:\t" + response);
        let error = {
            code : errorCodes.ERR_INVALID_PARAMETER,
            message : "Response is either null or undefined"
        }
        throw error // This also works fine
    }

    let options = {
        url : appConstants.URL_FACEBOOK_GRAPH_API,
        qs : { access_token : appConstants.TOKEN_PAGE_ACCESS },
        method : "POST",
        body : response,
        json : true
    };
    
    // Return a promise which needs to then be resolved for the next thing in the chain to get the data
    return request(options)
        .then(responseBody => {
            console.log("ResponseBody: \t" + responseBody)
            return responseBody
        })
        .catch(errorObj => {
            if (!errorObj.error.error.message) return
            let error = {
                code : errorCodes.ERR_FB_GRAPH_API,
                message : rejected.error.error.message
            }
            throw error; // This is where things go wrong
        })
        // This is going to be the exception you triggered in the previous catch block
        .catch(err => {
            console.error("Error while calling FB Graph API:\n" + err);
            let error = {
                code : errorCodes.ERR_UNMAPPED_ERROR,
                message : err
            };
        });
})
return Promise.resolve()
    .then(prBody)
    .then(responseBodyORError => {
        if (responseBodyORError.error) {return console.log('There was an error, catch simply recover chains')}
        // At this point responseBodyORError will only be the response body, since error checking is done
    })

于 2018-08-01T22:47:29.593 回答