【问题标题】:Returning a value from within a promise从 Promise 中返回一个值
【发布时间】:2016-11-10 01:14:11
【问题描述】:

我有一个注入服务的服务。子服务连接到 facebook api,并假设将用户的登录状态返回给父服务。我面临的问题是这个 fb api 调用使用了一个承诺,我试图根据子服务函数调用的值在父服务中执行一些逻辑。这样做的正确方法是什么?

这是我尝试过的:

facebook.service.ts

请注意,以下代码成功连接到 facebook api 并输出“已连接”**

checkLoginStatus() {
        this.FB.getLoginStatus( (response) => {
            console.log(response.status); //outputs "connected"
        });

}

但是,我试图将 promise 的响应中包含的值返回给父服务,所以我修改了代码如下...并得到错误:

Uncaught (in promise): TypeError: Cannot read property 'getLoginStatus' of undefined

facebook.service.ts

 FB:any;

    constructor() {
        facebook().then((FB) => {
            // Initialize SDK
            FB.init({
                appId      : '1111111111111111',
                cookie     : true,  // enable cookies to allow the server to access
                                    // the session
                xfbml      : true,  // parse social plugins on this page
                version    : 'v2.8' // use graph api version 2.5
            });

            this.FB = FB;

        });
    }

    checkLoginStatus() {
        this.FB.getLoginStatus( (response) => {
           return response.status; //"connected"
        });
    }

home.service.ts

constructor(@Inject(FacebookService) private fb:FacebookService) {
    this.authenticateFacebook();
}

authenticateFacebook() {
    this.fb.checkLoginStatus().then( (response) => {
        console.log(response); //should output connected
    });
}

【问题讨论】:

  • 如果没有打印,可能是传递给 this.FB.getLoginStatus() 的回调从未执行。可能是因为 getLoginStatus() 调用失败。如果出现错误,它可能需要第二次回调。这个FB.getLoginStatus() 方法的文档在哪里?
  • @JBNizet,getLoginStatus 成功并返回“已连接”
  • “返回”是什么意思。您没有使用this.FB.getLoginStatus() 返回的值。你正在传递一个回调。你怎么知道它返回什么(或传递给你的回调),因为什么都没有打印?同样,FB.getLoginStatus() 的文档是什么?您所指的只是允许加载 facebook 库。它没有记录方法 FB.getLoginStatus()。
  • 发布了文档。我知道它返回什么 b/c 我记录了对控制台的响应(请参阅编辑的代码)。事实上,getLoginStatus 在响应中包含一个字符串,表示身份验证成功,我正在尝试将其返回给父服务。

标签: angular typescript promise


【解决方案1】:

在您调用服务时,this.FB 仍未定义,如错误所示。那是因为初始化本身是异步的:facebook() 加载库,并且只有在加载时,this.FB 才会被初始化。在使用this.FB 之前,您只需要等待此初始化完成。不过修复相对简单:

private fbPromise: Promise<any>;

constructor() {
    this.fbPromise = facebook().then((FB) => {
        // Initialize SDK
        FB.init({
            appId      : '1111111111111111',
            cookie     : true,  // enable cookies to allow the server to access
                                // the session
            xfbml      : true,  // parse social plugins on this page
            version    : 'v2.8' // use graph api version 2.5
        });

        return FB;
    });
}

private authenticateFacebook(FB): Promise<any> {
    return new Promise((resolve, reject) => {
        FB.getLoginStatus(response => resolve(response));
    });
}

checkLoginStatus(): Promise<string> {
    return this.fbPromise
               .then(FB => this.authenticateFacebook(FB))
               .then(response => response.status);
}

【讨论】:

  • 感谢您的回复。但是,您完全忽略了这两个函数位于不同文件中的事实,并没有真正解决实际问题。目标是在home.service.ts 中输出登录状态。基本上,checkLoginStatus() 在一个单独的文件中,我试图避免在home.service.ts 文件中需要this.fbPromise...从头到尾阅读原件,这应该是有道理的。
  • 鳀鱼我不知道你在问什么了。
  • @Piotr,真的很简单,阅读原帖。在最上面,facebook.service.ts 代码 sn-p,“已连接”正在记录到控制台。因此,与 Facebook API 的所有通信都是成功的。现在,不是将此字符串记录到控制台,而是简单地将“已连接”字符串返回到home.service.ts 中的父服务。上述实现无论如何都无助于实现这一点。
  • 您可以做的唯一方法是将要调用的服务的引用传递给 facebook 服务,这样当它被 initd 时,您可以在其上执行一个函数(或接口)或者您可以使用 observable 而不是 promises,然后您可以在 facebook “连接” 以在您的第二个服务中触发某些内容时收听 observable 的更改。
  • 我们将不胜感激。
【解决方案2】:

只需将其包装在您可以返回的您自己的承诺中,并在您可以指定返回值的解析值中。

public authenticateFacebook(): Promise<any> {

        return new Promise((resolve, reject) => {
           this.fb.checkLoginStatus().then( response => {
                console.log(response); //should output connected
                resolve(response);
            });
        });

    }

【讨论】:

  • 感谢 Piotr 的回复。虽然这个答案看起来很有希望,但这对我不起作用......仍然没有错误。
  • 这将正常工作 - 我正在使用它。不是 facebook,而是作为返回值的一般原则。
  • 尝试添加reject(value)并查看是否有任何错误,可能checkLoginstatus会在出现错误时抛出错误,这就是resolve响应不起作用的原因。
  • 请查看更新的代码,现在收到一个新错误Uncaught (in promise): TypeError: Cannot read property 'getLoginStatus' of undefined,这是我在用自己的承诺包装之前没有得到的
  • 尝试将 response => 更改为 (response) => 否则可能是您注入它的方式,我不熟悉 @injection 语法。
猜你喜欢
  • 2014-10-21
  • 2017-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-17
  • 1970-01-01
相关资源
最近更新 更多