JavaScript的承诺等待结果

问题描述 投票:2回答:2

我开发一个应用程序做出反应,将通过ADAL Azure的广告进行身份验证。一切工作正常,但我需要在应用程序的开始加载JWT令牌。我想,我会换我的两个功能,这给回一个令牌的承诺,然后有条件地呈现它,但是由于某种原因,它并没有“等待”我的承诺来解决。

任何帮助将受到欢迎。干杯!

import React, { Component } from 'react';

import { library } from '@fortawesome/fontawesome-svg-core';
import { faIgloo, faBars } from '@fortawesome/free-solid-svg-icons';
import { initializeIcons } from '@uifabric/icons';
import { acquireToken, acquireGraphToken } from '../../adalConfig'

import Navbar from '../../common/navbar/navbar';
import Searchbar from '../../common/utils/searchBar/searchBar';
import LeftNavigation from '../../common/leftNavigation/leftNavigation';
import PageContainer from '../pageContainer/pageContainer';
import { IntlProvider } from 'react-intl';

import messages_en from '../../assets/translations/translations_en';
import messages_nl from '../../assets/translations/translations_nl';
import StylesheetLoader from '../../common/utils/stylesheetLoader/stylesheetLoader';
import ReactAI from 'react-appinsights';
import { connect } from 'react-redux';
import * as userActions from '../../store/users/actions';

initializeIcons();
library.add(faIgloo, faBars);

class App extends Component {

  state = {
    languageChoice: 'en',
    theme: 'red',
    tokensAreLoaded: false
  }

  componentWillMount() {

    let promise = new Promise((resolve, reject) => {
      const token = acquireToken();
      const graphToken = acquireGraphToken();

      if (token != '' && graphToken != '') {
        resolve(true);
      } else {
        reject(Error('promise failed'))
      }
    });

    promise.then( (value) => {
      this.setState({tokensAreLoaded: value});
    }, function (error){
      console.log('error getting promise value');
    })
  }

  componentDidMount() {
    this.props.onFetchCurrentUser();
  }    

  render() {

    if (this.state.tokensAreLoaded) {
      console.log('renderApp');
    } else {
      console.log('loading');
    }

    // Sets an interval that refreshes to get the token every 15 minutes
    // We use this because our custom API's do not automatically issue a
    // refresh token.
    setInterval(AppTokenRefresher, 900000);

    function AppTokenRefresher() {
      acquireToken();
      acquireGraphToken();
    } 

    const messages = {
        'nl': messages_nl,
        'en': messages_en
    };

    ReactAI.setAppContext({urlReferrer: document.referrer});
    // const Ai = ReactAI.ai();

    // function test() {
    //   Ai.trackEvent('Testing', { 'user': 'me' });
    // }

    const user = this.props.currentUser ? this.props.currentUser.name : 'test';

    return (
      <React.Fragment>
        <StylesheetLoader />
        {user}
        <IntlProvider locale={this.state.languageChoice} messages={messages[this.state.languageChoice]}>
          <div className="siteContainer">
            <Navbar currentUserProfile={this.props.currentUser}></Navbar>

            <div className="mobile-searchbar">
              <Searchbar />
            </div>

            <div className='page-container'>
              <aside>
                <LeftNavigation />
              </aside>

              <section className="main">
                <PageContainer />
            </section>

            </div>

          </div>
        </IntlProvider>

      </React.Fragment>
    );
  }
}

const mapStateToProps = state => {
  return {
      currentUserError: state.currentUserSlice.currentUserError,
      currentUserLoading: state.currentUserSlice.currentUserLoading,
      currentUser: state.currentUserSlice.currentUser,
      currentUserPicture: state.currentUserSlice.currentUserPicture
  }
}

const mapDispatchToProps= (dispatch) => {
  return {
      onFetchCurrentUser: () => dispatch(userActions.fetchCurrentUser()),
      onFetchCurrentUserPicture: () => dispatch(userActions.fetchCurrentUserPicture())
  }    
}

export default connect(mapStateToProps, mapDispatchToProps)(App);

我在我的诺言包装阿达尔辅助功能:

import { AuthenticationContext, adalFetch } from 'react-adal';

const adalConfig = {
    instance: 'https://login.microsoftonline.com/',
    clientId: '9e16003a',
    extraQueryParameter: 'nux=1',
    endpoints: {
        graphApi: 'https://graph.microsoft.com',
        oneApi: 'https://one365demo.onmicrosoft.com/b15a-3f1d0cf658f5'
    },
    postLogoutRedirectUri: window.location.origin,
    redirectUri: window.location.origin,
    cacheLocation: 'localStorage'
};

export const authContext = new AuthenticationContext(adalConfig);



export const adalGraphFetch = (fetch, url, options) =>
  adalFetch(authContext, adalConfig.endpoints.graphApi, fetch, url, options);

export const adalOneApiFetch = (fetch, url, options) =>
  adalFetch(authContext, adalConfig.endpoints.oneApi, fetch, url, options);

export const getToken = () => {
    return authContext.getCachedToken(authContext.config.clientId);
};

export const getGraphToken = () => {
    return authContext.getCachedToken('https://graph.microsoft.com');
};

export const acquireGraphToken = () => {  
    authContext.acquireToken(adalConfig.endpoints.graphApi, (message, token, msg) => {
        console.log('graph token', token);
        return token;
    })

    return null;
} 

export const acquireToken = () => {  
    authContext.acquireToken(adalConfig.endpoints.oneApi, (message, token, msg) => {
        console.log('the token', token);
        return token;
    })

    return null;
}
javascript reactjs promise
2个回答
3
投票

它看起来像AuthenticationContext#acquireToken是一个异步方法,即具有当令牌获取该被调用的回调(或当试图这样做失败)。

考虑重新定义围绕该呼叫acquireToken()让他们要么async,或阿达尔辅助方法,让他们返回传递给Promise回调被调用时进步一AuthenticationContext#acquireToken()

export const acquireGraphToken = () => {  

    /* Return promise as acquireToken() is async */
    return (new Promise(resolve => {
        authContext.acquireToken(adalConfig.endpoints.graphApi, (message, token, msg) => {
                console.log('graph token', token);

                /* Resolve enclosing promise with token */
                resolve(token); 
            })
        }));    
} 

export const acquireToken = () => {  

    /* Return promise as acquireToken() is async */
    return (new Promise(resolve => {
        authContext.acquireToken(adalConfig.endpoints.oneApi, (message, token, msg) => {
            console.log('the token', token);

            /* Resolve enclosing promise with token */
            resolve(token); 
        })
    }));
}

有了您的帮助模块在应用这些更改,你再需要更新您的componentWillMount()组件钩正确地整合这些方法,以确保组件状态与{tokensAreLoaded: true}一旦两个令牌成功获得更新:

componentWillMount() {

    /* Issue request for both tokens to get aquired */
    Promise.all([
        acquireToken(),
        acquireGraphToken()
    ])
    .then(([ token, graphToken ]) => {

        /* On resolving both requests, ensure tokens are value before proceeding or reject (as before) */
        if (token != '' && graphToken != '') {
            resolve(token);
        } else {
            reject(Error('promise failed'))
        }
    })
    .then(() => {

        /* On success, update state */
        this.setState({tokensAreLoaded: true});
    })
  }

希望这可以帮助!


0
投票

我建议引入某种负载通知,直到令牌被取出。你可以等待令牌componentDidMount这样你就不会阻止堆栈

async componentDidMount() {
    try {
        const token = await this.getToken();
        this.setState({tokensAreLoaded: true, token});
    } catch (e) {
        throw new Error (e);
    }
}
getToken () {
    return new Promise((resolve, reject) => {
        const token = acquireToken();
        const graphToken = acquireGraphToken();

        if (token != '' && graphToken != '') {
            resolve(token);
        } else {
           reject(Error('promise failed'))
        }
    });
}

而在你render方法:

render () {
    if (!this.state.tokensAreLoaded) {
        return (<p>Authorizing</p>);
    }
    return (
       // the stuff you want to display when token is ready
    )

}
© www.soinside.com 2019 - 2024. All rights reserved.