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