1. 程式人生 > >Promise用法(以QQ授權為例)

Promise用法(以QQ授權為例)

Promise是ES6的一個新特性,能夠很好的解決js非同步處理的callback巢狀問題。

在做三方授權登入時,總是要連續調第三方的多個介面,這裡使用Promise方法再合適不過了。

下面,我以node後臺調取QQ使用者資訊為例,解釋一下Promise的用法:

1、我使用的是express框架,封裝了QQ請求的方法

const qs = require('querystring');
const https = require('https');

function loginByQQ(code, cb) {
  new Promise((resolve)=>{
    //第一步:獲取token
    let queryData = {
      grant_type: 'authorization_code', //預設值寫死
      client_id: '**********', //應用APPID
      redirect_uri: '***************', //回撥地址
      client_secret: '***************', //應用祕鑰
      code: code //傳入的code值
    };
    https.get("https://graph.qq.com/oauth2.0/token?" + qs.stringify(queryData), (resp) => {
      resp.setEncoding('utf8');
      resp.on('data', (chunk) => {
        if ('獲取token成功') {
          let token = '獲取到的token';
          resolve(token); //結束當前步驟,傳送引數給下一個步驟
        } else {
          let errMsg = '騰訊返回錯誤資訊';
          cb({
            result: false,
            msg: errMsg
          });
        }
      });
    })
  }).then((token)=>{ //token為上一個步驟傳遞的引數
    // 第二步:獲取openId
    return new Promise((resolve)=>{
      https.get("https://graph.qq.com/oauth2.0/me?access_token=" + token, (resp) => {
        resp.setEncoding('utf8');
        resp.on('data', (chunk) => {
          let openId = '獲取到的openid';
          resolve({
            openId: openId,
            token: token
          }); //結束當前步驟,傳送引數給下一個步驟
        })
      })
    })
  }).then((val)=>{ //val為上一個步驟傳遞的引數
    // 第三步:獲取使用者資訊
    let userInfoQuery = {
      access_token: val.token,
      oauth_consumer_key: '*********',
      openid: val.openId
    };
    https.get("https://graph.qq.com/user/get_user_info?" + qs.stringify(userInfoQuery), (resp) => {
      resp.setEncoding('utf8');
      resp.on('data', (chunk) => {
        let userInfo = JSON.parse(chunk); //獲取到的使用者資訊
        cb({
          result: true,
          user: userInfo
        });
      })
    })
  });
}

module.exports = loginByQQ;

2、呼叫loginByQQ方法,傳入code和callback引數

loginByQQ('dsau8412383489deway87', (res)=>{
  console.log(res);
})

3、注意

前面的步驟,每次都要new Promise方法,第二步以後,在then裡面return 當前Promise,最後一步後面沒有可執行函式,所以可以省略new Promise。

騰訊介面返回值需要做相應處理,我已經省略,大家根據情況,自行處理。

Promise有resolve和reject兩個引數。我的程式錯誤採用callback傳遞,所以沒有用reject。

resolve作用:結束當前步驟,傳值給下一個步驟,執行下一個步驟。

reject作用:遇到錯誤,結束所有步驟,丟擲異常,程式停止