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作用:遇到错误,结束所有步骤,抛出异常,程序停止

Promise是一种异步编程的解决方案,它可以避免回调地狱,使得异步操作更加清晰和易于维护。Promise有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。当Promise处于pending状态时,可以转换为fulfilled或rejected状态,一旦转换为其中一种状态,就不可再转换为其他状态。 Promise的基本用法如下: ```javascript const promise = new Promise((resolve, reject) => { // 异步操作 if (/* 异步操作成功 */) { resolve(value); // 将Promise状态设置为fulfilled,并将异步操作的结果传递给回调函数 } else { reject(error); // 将Promise状态设置为rejected,并将错误信息传递给回调函数 } }); promise.then((value) => { // 异步操作成功时的回调函数 }, (error) => { // 异步操作失败时的回调函数 }); ``` 另外,Promise还提供了一些静态方法,如Promise.resolve和Promise.reject,可以方便地创建已经处于fulfilled或rejected状态的Promise对象,以及Promise.all和Promise.race等方法,可以处理多个Promise对象的状态。 下面是一个使用Promise的例子,通过异步加载图片并在加载完成后显示图片: ```javascript function loadImageAsync(url) { return new Promise((resolve, reject) => { const img = new Image(); img.onload = function() { resolve(img); }; img.onerror = function() { reject(new Error('Could not load image at ' + url)); }; img.src = url; }); } loadImageAsync('https://example.com/image.jpg') .then((img) => { document.body.appendChild(img); }) .catch((error) => { console.error(error); }); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值