真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

php如何實(shí)現(xiàn)小程序登錄功能

本篇內(nèi)容介紹了“php如何實(shí)現(xiàn)小程序登錄功能”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)公司!專注于網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開(kāi)發(fā)、微信小程序定制開(kāi)發(fā)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了濠江免費(fèi)建站歡迎大家使用!

RequestTask說(shuō)明

方法說(shuō)明
RequestTask.abort()中斷請(qǐng)求任務(wù)。
RequestTask.onHeadersReceived(function callback)監(jiān)聽(tīng) HTTP Response Header 事件。會(huì)比請(qǐng)求完成事件更早。
RequestTask.offHeadersReceived(function callback)取消監(jiān)聽(tīng) HTTP Response Header 事件。
RequestTask.onChunkReceived(function callback)監(jiān)聽(tīng) Transfer-Encoding Chunk Received 事件。當(dāng)接收到新的chunk時(shí)觸發(fā)。
RequestTask.offChunkReceived(function callback)取消監(jiān)聽(tīng) Transfer-Encoding Chunk Received 事件。

wx.request(Object object)屬性

此處只列比較常用的屬性,全部屬性請(qǐng)查看鏈接。

屬性類型默認(rèn)值必填說(shuō)明
urlstring
開(kāi)發(fā)者服務(wù)器接口地址
datastring/object/ArrayBuffer
請(qǐng)求的參數(shù)
headerObject
設(shè)置請(qǐng)求的 header,header 中不能設(shè)置 Referer。 content-type 默認(rèn)為 application/json
timeoutnumber
超時(shí)時(shí)間,單位為毫秒
methodstringGETHTTP 請(qǐng)求方法
successfunction
接口調(diào)用成功的回調(diào)函數(shù)
failfunction
接口調(diào)用失敗的回調(diào)函數(shù)
completefunction
接口調(diào)用結(jié)束的回調(diào)函數(shù)(調(diào)用成功、失敗都會(huì)執(zhí)行)哪怕是abort掉的請(qǐng)求!

總結(jié)一下:所有的小程序接口基本上都有兩個(gè)特征:

  • 參數(shù)都是一個(gè)對(duì)象。便于記憶的同時(shí)方便擴(kuò)展。

  • 都有相同的結(jié)果處理方式:都有success、fail、complete三個(gè)回調(diào)屬性。

接口執(zhí)行的各種情況下的errMsg對(duì)象介紹。

回調(diào)屬性errMsg對(duì)象
success{errMsg:"request:ok"...}
fail{errMsg:"request:fail "...} 有的系統(tǒng)這個(gè)fail后面有個(gè)空格,所以要使用這個(gè)判斷,最好是使用正則表達(dá)式。也可以使用indexOf函數(shù),大于-1進(jìn)行判斷。
abort{errMsg:"request:fail abort"...}

示例代碼

  let reqTask = wx.request({
      url: getApp().globalData.api,
      success(res) {
        if (res.errMsg === "request:ok") console.log("res", res);
      },
      fail(err) {
        // if(err.errMsg.indexOf('request:fail')>-1) console.log('err', err);
        if (/^request:fail/i.test(err.errMsg)) console.log("err", err);
      },
      complete(res) {
        console.log("resOrErr", res);
      },
    });
   const reqTaskOnHeadersReceived = (headers) => {
      reqTask.offHeadersReceived(reqTaskOnHeadersReceived);
      console.log("headers", headers);
      // 由于請(qǐng)求還未完全結(jié)束,所以我們沒(méi)辦法獲得請(qǐng)求的狀態(tài)碼,但是我們可以通過(guò)返回的requestBody的長(zhǎng)度來(lái)進(jìn)行判斷。
      // 兩點(diǎn)說(shuō)明:1. 兩個(gè)~~可以把字符串?dāng)?shù)字快速轉(zhuǎn)化為數(shù)字。
      // 2. 為什么取小于19,是由于后臺(tái)返回沒(méi)有權(quán)限的requestBody的時(shí)候Content-length為“18”,正常情況下是大于19的。所以具體多少得看一下具體情況。
      if (~~headers.header["Content-length"] < 19) reqTask.abort();
    };
    reqTask.onHeadersReceived(reqTaskOnHeadersReceived);

小程序登錄接口

  • wx.getUserProfile(Object object)

    獲取用戶信息。頁(yè)面產(chǎn)生點(diǎn)擊事件(例如 buttonbindtap 的回調(diào)中)后才可調(diào)用,每次請(qǐng)求都會(huì)彈出授權(quán)窗口,用戶同意后返回 userInfo。該接口用于替換 wx.getUserInfo,詳見(jiàn) 用戶信息接口調(diào)整說(shuō)明。

  • wx.checkSession(Object object)

    檢查登錄態(tài)是否過(guò)期。 通過(guò) wx.login 接口獲得的用戶登錄態(tài)擁有一定的時(shí)效性。用戶越久未使用小程序,用戶登錄態(tài)越有可能失效。反之如果用戶一直在使用小程序,則用戶登錄態(tài)一直保持有效。具體時(shí)效邏輯由微信維護(hù),對(duì)開(kāi)發(fā)者透明。開(kāi)發(fā)者只需要調(diào)用 wx.checkSession 接口檢測(cè)當(dāng)前用戶登錄態(tài)是否有效。

    登錄態(tài)過(guò)期后開(kāi)發(fā)者可以再調(diào)用 wx.login 獲取新的用戶登錄態(tài)。調(diào)用成功說(shuō)明當(dāng)前 session_key 未過(guò)期,調(diào)用失敗說(shuō)明 session_key 已過(guò)期。更多使用方法詳見(jiàn) 小程序登錄。

  • wx.login(Object object)

    調(diào)用接口獲取登錄憑證(code)。通過(guò)憑證進(jìn)而換取用戶登錄態(tài)信息,包括用戶在當(dāng)前小程序的唯一標(biāo)識(shí)(openid)、微信開(kāi)放平臺(tái)帳號(hào)下的唯一標(biāo)識(shí)(unionid,若當(dāng)前小程序已綁定到微信開(kāi)放平臺(tái)帳號(hào))及本次登錄的會(huì)話密鑰(session_key)等。用戶數(shù)據(jù)的加解密通訊需要依賴會(huì)話密鑰完成。更多使用方法詳見(jiàn) 小程序登錄。

后端登錄接口代碼實(shí)現(xiàn)

后端使用NodeJS,web框架KOA版本^2.13.4,路由框架@koa/router版本^10.1.1,框架request,版本 ^2.88.2,jsonwebtoken用來(lái)加密解密token信息,版本^8.5.1

// app.js
const Koa = require("koa");
const Router = require("@koa/router");
const WeixinAuth = require("./lib/koa2-weixin-auth");
const jsonwebtoken = require("jsonwebtoken");

const app = new Koa();
// 小程序機(jī)票信息
const miniProgramAppId = "*********";
const miniProgramAppSecret = "***********";
const weixinAuth = new WeixinAuth(miniProgramAppId, miniProgramAppSecret);

const JWT_SECRET = "JWTSECRET";
// 路由中間件需要安裝@koa/router
// 開(kāi)啟一個(gè)帶群組的路由
const router = new Router({
  prefix: "/user",
});
// 這是正規(guī)的登陸方法
// 添加一個(gè)參數(shù),sessionKeyIsValid,代表sessionKey是否還有效
router.post("/weixin-login", async (ctx) => {
  let { code, userInfo, encryptedData, iv, sessionKeyIsValid } =
    ctx.request.body;
   // 解析openid
  const token = await weixinAuth.getAccessToken(code);
  userInfo.openid = token.data.openid;
  // 這里可以自己進(jìn)行處理,比方說(shuō)記錄到數(shù)據(jù)庫(kù),處理token等
  let authorizationToken = jsonwebtoken.sign(
    { name: userInfo.nickName },
    JWT_SECRET,
    { expiresIn: "1d" }
  );
  Object.assign(userInfo, { authorizationToken });
  ctx.status = 200;
  ctx.body = {
    code: 200,
    msg: "ok",
    data: userInfo,
  };
});
// lib/koa2-weixin-auth.js
const querystring = require("querystring");
const request = require("request");

const AccessToken = function (data) {
  if (!(this instanceof AccessToken)) {
    return new AccessToken(data);
  }
  this.data = data;
};

/*!
 * 檢查AccessToken是否有效,檢查規(guī)則為當(dāng)前時(shí)間和過(guò)期時(shí)間進(jìn)行對(duì)比
 *
 * Examples:
 * ```
 * token.isValid();
 * ```
 */
AccessToken.prototype.isValid = function () {
  return (
    !!this.data.session_key &&
    new Date().getTime() < this.data.create_at + this.data.expires_in * 1000
  );
};

/**
 * 根據(jù)appid和appsecret創(chuàng)建OAuth接口的構(gòu)造函數(shù)
 * 如需跨進(jìn)程跨機(jī)器進(jìn)行操作,access token需要進(jìn)行全局維護(hù)
 * 使用使用token的優(yōu)先級(jí)是:
 *
 * 1. 使用當(dāng)前緩存的token對(duì)象
 * 2. 調(diào)用開(kāi)發(fā)傳入的獲取token的異步方法,獲得token之后使用(并緩存它)。

 * Examples:
 * ```
 * var OAuth = require('oauth');
 * var api = new OAuth('appid', 'secret');
 * ```
 * @param {String} appid 在公眾平臺(tái)上申請(qǐng)得到的appid
 * @param {String} appsecret 在公眾平臺(tái)上申請(qǐng)得到的app secret
 */
const Auth = function (appid, appsecret) {
  this.appid = appid;
  this.appsecret = appsecret;
  this.store = {};

  this.getToken = function (openid) {
    return this.store[openid];
  };

  this.saveToken = function (openid, token) {
    this.store[openid] = token;
  };
};

/**
 * 獲取授權(quán)頁(yè)面的URL地址
 * @param {String} redirect 授權(quán)后要跳轉(zhuǎn)的地址
 * @param {String} state 開(kāi)發(fā)者可提供的數(shù)據(jù)
 * @param {String} scope 作用范圍,值為snsapi_userinfo和snsapi_base,前者用于彈出,后者用于跳轉(zhuǎn)
 */
Auth.prototype.getAuthorizeURL = function (redirect_uri, scope, state) {
  return new Promise((resolve, reject) => {
    const url = "https://open.weixin.qq.com/connect/oauth3/authorize";
    let info = {
      appid: this.appid,
      redirect_uri: redirect_uri,
      scope: scope || "snsapi_base",
      state: state || "",
      response_type: "code",
    };
    resolve(url + "?" + querystring.stringify(info) + "#wechat_redirect");
  });
};

/*!
 * 處理token,更新過(guò)期時(shí)間
 */
Auth.prototype.processToken = function (data) {
  data.create_at = new Date().getTime();
  // 存儲(chǔ)token
  this.saveToken(data.openid, data);
  return AccessToken(data);
};

/**
 * 根據(jù)授權(quán)獲取到的code,換取access token和openid
 * 獲取openid之后,可以調(diào)用`wechat.API`來(lái)獲取更多信息
 * @param {String} code 授權(quán)獲取到的code
 */
Auth.prototype.getAccessToken = function (code) {
  return new Promise((resolve, reject) => {
    const url = "https://api.weixin.qq.com/sns/jscode2session";
    //由于此框架版本很久沒(méi)有更新了,此處地址發(fā)生了變化,需要修改為以上地址,不然會(huì)出現(xiàn)
    //41008錯(cuò)誤。這也是沒(méi)有直接使用框架,引用本地使用的原因。
    // const url = "https://api.weixin.qq.com/sns/oauth3/access_token";
    const info = {
      appid: this.appid,
      secret: this.appsecret,
      js_code: code,
      grant_type: "authorization_code",
    };
    request.post(url, { form: info }, (err, res, body) => {
      if (err) {
        reject(err);
      } else {
        const data = JSON.parse(body);
        resolve(this.processToken(data));
      }
    });
  });
};

/**
 * 根據(jù)refresh token,刷新access token,調(diào)用getAccessToken后才有效
 * @param {String} refreshToken refreshToken
 */
Auth.prototype.refreshAccessToken = function (refreshToken) {
  return new Promise((resolve, reject) => {
    const url = "https://api.weixin.qq.com/sns/oauth3/refresh_token";
    var info = {
      appid: this.appid,
      grant_type: "refresh_token",
      refresh_token: refreshToken,
    };
    request.post(url, { form: info }, (err, res, body) => {
      if (err) {
        reject(err);
      } else {
        const data = JSON.parse(body);
        resolve(this.processToken(data));
      }
    });
  });
};

/**
 * 根據(jù)openid,獲取用戶信息。
 * 當(dāng)access token無(wú)效時(shí),自動(dòng)通過(guò)refresh token獲取新的access token。然后再獲取用戶信息
 * @param {Object|String} options 傳入openid或者參見(jiàn)Options
 */
Auth.prototype.getUser = async function (openid) {
  const data = this.getToken(openid);
  console.log("getUser", data);
  if (!data) {
    var error = new Error(
      "No token for " + options.openid + ", please authorize first."
    );
    error.name = "NoOAuthTokenError";
    throw error;
  }
  const token = AccessToken(data);
  var accessToken;
  if (token.isValid()) {
    accessToken = token.data.session_key;
  } else {
    var newToken = await this.refreshAccessToken(token.data.refresh_token);
    accessToken = newToken.data.session_key;
  }
  console.log("accessToken", accessToken);
  return await this._getUser(openid, accessToken);
};

Auth.prototype._getUser = function (openid, accessToken, lang) {
  return new Promise((resolve, reject) => {
    const url = "https://api.weixin.qq.com/sns/userinfo";
    const info = {
      access_token: accessToken,
      openid: openid,
      lang: lang || "zh_CN",
    };
    request.post(url, { form: info }, (err, res, body) => {
      if (err) {
        reject(err);
      } else {
        resolve(JSON.parse(body));
      }
    });
  });
};

/**
 * 根據(jù)code,獲取用戶信息。
 * @param {String} code 授權(quán)獲取到的code
 */
Auth.prototype.getUserByCode = async function (code) {
  const token = await this.getAccessToken(code);
  return await this.getUser(token.data.openid);
};

module.exports = Auth;

小程序端登錄代碼實(shí)現(xiàn)



    微信登錄
    
        登錄
    
// pages/index.js
Page({
  /**
   * 頁(yè)面的初始數(shù)據(jù)
   */
  data: {},
  // 正確的登錄方式
  getUserProfile() {
    // 推薦使用wx.getUserProfile獲取用戶信息,開(kāi)發(fā)者每次通過(guò)該接口獲取用戶個(gè)人信息均需用戶確認(rèn)
    // 開(kāi)發(fā)者妥善保管用戶快速填寫(xiě)的頭像昵稱,避免重復(fù)彈窗
    wx.getUserProfile({
      desc: "用于完善會(huì)員資料", // 聲明獲取用戶個(gè)人信息后的用途,后續(xù)會(huì)展示在彈窗中,請(qǐng)謹(jǐn)慎填寫(xiě)
      success: (res) => {
        let { userInfo, encryptedData, iv } = res;
        const requestLoginApi = (code) => {
          // 發(fā)起網(wǎng)絡(luò)請(qǐng)求
          wx.request({
            url: "http://localhost:3000/user/weixin-login",
            method: "POST",
            header: {
              "content-type": "application/json",
            },
            data: {
              code,
              userInfo,
              encryptedData,
              iv,
            },
            success(res) {
              console.log("請(qǐng)求成功", res.data);
              let token = res.data.data.authorizationToken;
              wx.setStorageSync("token", token);
              onUserLogin(token);
              console.log("authorization", token);
            },
            fail(err) {
              console.log("請(qǐng)求異常", err);
            },
          });
        };
        const onUserLogin = (token) => {
          getApp().globalData.token = token;
          wx.showToast({
            title: "登錄成功了",
          });
        };
        //必須進(jìn)行session是否過(guò)期檢查,不然會(huì)出現(xiàn)第一次點(diǎn)擊登錄,服務(wù)器報(bào)Illegal Buffer
        //的錯(cuò)誤,但是第二次點(diǎn)擊登錄正常。
        wx.checkSession({
          success: (res) => {
            // session_key 未過(guò)期,并且在本生命周期一直有效
            console.log("在登陸中");
            let token = wx.getStorageSync("token");
            if (token) onUserLogin(token);
          },
          fail: (res) => {
            // session_key已經(jīng)失效,需要重新執(zhí)行登錄流程
            wx.login({
              success(res0) {
                if (res0.code) {
                  requestLoginApi(res0.code);
                } else {
                  console.log("登錄失敗!" + res0.errMsg);
                }
              },
            });
          },
        });
      },
    });
  },
});

針對(duì)登錄代碼可以做哪些優(yōu)化?

對(duì)于一個(gè)軟件,就代碼層面而言,需要追求最基本的幾個(gè)方面(遠(yuǎn)不止這些,但是先姑且先做個(gè)好這些吧):

  • 可維護(hù)性(maintainability)

    所謂的“維護(hù)”無(wú)外乎就是修改 bug、修改老的代碼、添加新的代碼之類的工作。所謂“代碼易維護(hù)”就是指,在不破壞原有代碼設(shè)計(jì)、不引入新的 bug 的情況下,能夠快速地修改或者添加代碼。所謂“代碼不易維護(hù)”就是指,修改或者添加代碼需要冒著極大的引入新 bug 的風(fēng)險(xiǎn),并且需要花費(fèi)很長(zhǎng)的時(shí)間才能完成。

  • 可讀性(readability)

    軟件設(shè)計(jì)大師 Martin Fowler 曾經(jīng)說(shuō)過(guò):“Any fool can write code that a computer can understand. Good programmers write code that humans can understand.”翻譯成中文就是:“任何傻瓜都會(huì)編寫(xiě)計(jì)算機(jī)能理解的代碼。好的程序員能夠編寫(xiě)人能夠理解的代碼?!盙oogle 內(nèi)部甚至專門(mén)有個(gè)認(rèn)證就叫作 Readability。只有拿到這個(gè)認(rèn)證的工程師,才有資格在 code review 的時(shí)候,批準(zhǔn)別人提交代碼??梢?jiàn)代碼的可讀性有多重要,畢竟,代碼被閱讀的次數(shù)遠(yuǎn)遠(yuǎn)超過(guò)被編寫(xiě)和執(zhí)行的次數(shù)。我們需要看代碼是否符合編碼規(guī)范、命名是否達(dá)意、注釋是否詳盡、函數(shù)是否長(zhǎng)短合適、模塊劃分是否清晰、是否符合高內(nèi)聚低耦合等等。

  • 可擴(kuò)展性(extensibility)

    可擴(kuò)展性也是一個(gè)評(píng)價(jià)代碼質(zhì)量非常重要的標(biāo)準(zhǔn)。代碼預(yù)留了一些功能擴(kuò)展點(diǎn),你可以把新功能代碼,直接插到擴(kuò)展點(diǎn)上,而不需要因?yàn)橐砑右粋€(gè)功能而大動(dòng)干戈,改動(dòng)大量的原始代碼。

  • 可復(fù)用性(reusability)

    代碼的可復(fù)用性可以簡(jiǎn)單地理解為,盡量減少重復(fù)代碼的編寫(xiě),復(fù)用已有的代碼。

那么接下來(lái)就來(lái)優(yōu)化一下代碼吧:

模塊化

可以把登錄的代碼模塊化,代碼如下:

// lib/login.js
function loginWithCallback(cb) {
  // 推薦使用wx.getUserProfile獲取用戶信息,開(kāi)發(fā)者每次通過(guò)該接口獲取用戶個(gè)人信息均需用戶確認(rèn)
  // 開(kāi)發(fā)者妥善保管用戶快速填寫(xiě)的頭像昵稱,避免重復(fù)彈窗
  wx.getUserProfile({
    desc: "用于完善會(huì)員資料", // 聲明獲取用戶個(gè)人信息后的用途,后續(xù)會(huì)展示在彈窗中,請(qǐng)謹(jǐn)慎填寫(xiě)
    success: (res) => {
      let { userInfo, encryptedData, iv } = res;
      const requestLoginApi = (code) => {
        // 發(fā)起網(wǎng)絡(luò)請(qǐng)求
        wx.request({
          url: "http://localhost:3000/user/weixin-login",
          method: "POST",
          header: {
            "content-type": "application/json",
          },
          data: {
            code,
            userInfo,
            encryptedData,
            iv,
          },
          success(res) {
            console.log("請(qǐng)求成功", res.data);
            let token = res.data.data.authorizationToken;
            wx.setStorageSync("token", token);
            onUserLogin(token);
            console.log("authorization", token);
          },
          fail(err) {
            console.log("請(qǐng)求異常", err);
          },
        });
      };

      const onUserLogin = (token) => {
        getApp().globalData.token = token;
        wx.showToast({
          title: "登錄成功了",
        });
        if (cb && typeof cb == "function") cb(token);
      };
      wx.checkSession({
        success: (res) => {
          // session_key 未過(guò)期,并且在本生命周期一直有效
          console.log("在登陸中");
          let token = wx.getStorageSync("token");
          if (token) onUserLogin(token);
        },
        fail: (res) => {
          // session_key已經(jīng)失效,需要重新執(zhí)行登錄流程
          wx.login({
            success(res0) {
              if (res0.code) {
                requestLoginApi(res0.code);
              } else {
                console.log("登錄失敗!" + res0.errMsg);
              }
            },
          });
        },
      });
    },
  });
}

export default loginWithCallback;

Promise化

回調(diào)地獄問(wèn)題,不利于代碼的閱讀,所以接下來(lái)我們基于Promise進(jìn)行代碼優(yōu)化。有了 Promise 對(duì)象,就可以將異步操作以同步操作的流程表達(dá)出來(lái),避免了層層嵌套的回調(diào)函數(shù)。此外,Promise 對(duì)象提供統(tǒng)一的接口,使得控制異步操作更加容易。

Promise的幾個(gè)方法簡(jiǎn)介

方法名說(shuō)明
Promise.prototype.then方法返回的是一個(gè)新的 Promise 對(duì)象,因此可以采用鏈?zhǔn)綄?xiě)法。這種設(shè)計(jì)使得嵌套的異步操作,可以被很容易得改寫(xiě),從回調(diào)函數(shù)的"橫向發(fā)展"改為"向下發(fā)展"。
Promise.prototype.catch是 Promise.prototype.then(null, rejection) 的別名,用于指定發(fā)生錯(cuò)誤時(shí)的回調(diào)函數(shù)。Promise 對(duì)象的錯(cuò)誤具有"冒泡"性質(zhì),會(huì)一直向后傳遞,直到被捕獲為止。也就是說(shuō),錯(cuò)誤總是會(huì)被下一個(gè) catch 語(yǔ)句捕獲。
Promise.prototype.finally方法返回一個(gè)Promise。在promise結(jié)束時(shí),無(wú)論結(jié)果是fulfilled或者是rejected,都會(huì)執(zhí)行指定的回調(diào)函數(shù)。這為在Promise是否成功完成后都需要執(zhí)行的代碼提供了一種方式。
Promise.all這避免了同樣的語(yǔ)句需要在then()catch()中各寫(xiě)一次的情況。Promise.all 方法用于將多個(gè) Promise 實(shí)例,包裝成一個(gè)新的 Promise 實(shí)例。Promise.all 方法接受一個(gè)數(shù)組作為參數(shù),var p = Promise.all([p1,p2,p3]);p1、p2、p3 都是 Promise 對(duì)象的實(shí)例。(Promise.all 方法的參數(shù)不一定是數(shù)組,但是必須具有 iterator 接口,且返回的每個(gè)成員都是 Promise 實(shí)例。)p 的狀態(tài)由 p1、p2、p3 決定,分成兩種情況。  (1)只有p1、p2、p3的狀態(tài)都變成fulfilled,p的狀態(tài)才會(huì)變成fulfilled,此時(shí)p1、p2、p3的返回值組成一個(gè)數(shù)組,傳遞給p的回調(diào)函數(shù)。 (2)只要p1、p2、p3之中有一個(gè)被rejected,p的狀態(tài)就變成rejected,此時(shí)第一個(gè)被reject的實(shí)例的返回值,會(huì)傳遞給p的回調(diào)函數(shù)。
Promise.racePromise.race 方法同樣是將多個(gè) Promise 實(shí)例,包裝成一個(gè)新的 Promise 實(shí)例。var p = Promise.race([p1,p2,p3]);上面代碼中,只要p1、p2、p3之中有一個(gè)實(shí)例率先改變狀態(tài),p的狀態(tài)就跟著改變。那個(gè)率先改變的Promise實(shí)例的返回值,就傳遞給p的返回值。
Promise.any接收一個(gè)Promise可迭代對(duì)象,只要其中的一個(gè) promise 成功,就返回那個(gè)已經(jīng)成功的 promise 。所有子實(shí)例都處于rejected狀態(tài),總的promise才處于rejected狀態(tài)。
Promise.allSettled返回一個(gè)在所有給定的promise都已經(jīng)fulfilledrejected后的promise,并帶有一個(gè)對(duì)象數(shù)組,每個(gè)對(duì)象表示對(duì)應(yīng)的promise結(jié)果。相比之下,Promise.all() 更適合彼此相互依賴或者在其中任何一個(gè)reject時(shí)立即結(jié)束。

小程序API接口Promise化并且把需要登錄的調(diào)用接口模塊化

1、安裝插件。請(qǐng)先查看npm支持文檔。

npm install --save miniprogram-api-promise

2、在微信開(kāi)發(fā)者工具右方詳情中勾選使用npm模塊,并在菜單欄工具中點(diǎn)擊構(gòu)建npm。

3、初始化代碼。

// app.js
import {promisifyAll} from 'miniprogram-api-promise'
import login from "../lib/login";
const wxp ={}
promisifyAll(wx,wxp)
// 需要token的請(qǐng)求統(tǒng)一處理登錄和設(shè)置header,并且處理錯(cuò)誤信息
wxp.requestNeedLogin = async function (args) {
  let token = wx.getStorageSync("token");
  if (!token) {
    token = await loginWithPromise();
  }
  if (!args.header) args.header = {};
  args.header["Authorization"] = `Bearer ${token}`;
  return wxp.request(args).catch(console.error);
};
// app.js
App({
  wxp:wxp,
});

4、改寫(xiě)login.js代碼

// lib/login.js
function login() {
  return new Promise((resolve, reject) => {
    // 推薦使用wx.getUserProfile獲取用戶信息,開(kāi)發(fā)者每次通過(guò)該接口獲取用戶個(gè)人信息均需用戶確認(rèn)
    // 開(kāi)發(fā)者妥善保管用戶快速填寫(xiě)的頭像昵稱,避免重復(fù)彈窗
    wx.getUserProfile({
      desc: "用于完善會(huì)員資料", // 聲明獲取用戶個(gè)人信息后的用途,后續(xù)會(huì)展示在彈窗中,請(qǐng)謹(jǐn)慎填寫(xiě)
       success:async (res0) => {
        let {
          userInfo,
          encryptedData,
          iv
        } = res0;
        const app = getApp();
        try {
          app.wxp.checkSession();
        } catch (err) {
          reject(err);
        }
        let token = wx.getStorageSync("token");
        if (!token) {
          let res1 = await app.wxp.login().catch(err => reject(err));
          let code = res1.code;
          let res = await app.wxp.request({
            url: "http://localhost:3000/user/weixin-login",
            method: "POST",
            header: {
              "content-type": "application/json",
            },
            data: {
              code,
              userInfo,
              encryptedData,
              iv,
            }
          }).catch(err => reject(err));
          token = res.data.data.authorizationToken;
          wx.setStorageSync("token", token);
          app.globalData.token = token;
          wx.showToast({
            title: "登錄成功了",
          });
          resolve(token);
        }
      },
    });
  })
}

export default login;

5、調(diào)用代碼


  需要登錄的請(qǐng)求調(diào)用
  
    請(qǐng)求1
    請(qǐng)求2
  
// pages/index.js
Page({
  /**
   * 頁(yè)面的初始數(shù)據(jù)
   */
  data: {},
  request1() {
    getApp().wxp.requestNeedLogin({
        url: "http://localhost:3000/user/home?name=andying",
      }).then(console.log)
  },
  request2() {
    getApp().wxp.requestNeedLogin({
        url: "http://localhost:3000/user/home?name=eva",
      }).then(console.log)
  },
});

“php如何實(shí)現(xiàn)小程序登錄功能”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!


本文名稱:php如何實(shí)現(xiàn)小程序登錄功能
鏈接URL:http://weahome.cn/article/jsjdhc.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部