一级片大奶子_色又黄又爽18禁免费视频_热久久久久久久_久久久精品一区二区_日韩av不卡在线播放_精品国内自产拍在线观看视频

注冊登錄

小程序云開發教程之云函數路由高級玩法

2018-09-25
導讀:在掘金開發者大會上,在推薦實踐那里,我有提到一種云函數的用法,我們可以將相同的一些操作,比如用戶管理、支付邏輯,按照業務的相似性,歸類到一個云函數里,這樣比較方便管理、排...
 

在掘金開發者大會上,在推薦實踐那里,我有提到一種云函數的用法,我們可以將相同的一些操作,比如用戶管理、支付邏輯,按照業務的相似性,歸類到一個云函數里,這樣比較方便管理、排查問題以及邏輯的共享。甚至如果你的小程序的后臺邏輯不復雜,請求量不是特別大,完全可以在云函數里面做一個單一的微服務,根據路由來處理任務。

tcb-router 介紹及用法

為了方便大家試用,咱們騰訊云 Tencent Cloud Base 團隊開發了 tcb-router,云函數路由管理庫方便大家使用。

那具體怎么使用 tcb-router 去實現上面提到的架構呢?下面我會逐一舉例子。

架構一:一個云函數處理一個任務
這種架構下,其實不需要用到 tcb-router,像普通那樣寫好云函數,然后在小程序端調用就可以了。

  • 云函數
// 函數 router
exports.main = (event, context) => {
    return {
        code: 0,
        message: 'success'
    };
};
  • 小程序端
wx.cloud.callFunction({
      name: 'router',
      data: {
        name: 'tcb',
        company: 'Tencent'
      }
    }).then((res) => {
      console.log(res);
    }).catch((e) => {
      console.log(e);
});

架構二: 按請求給云函數歸類
此類架構就是將相似的請求歸類到同一個云函數處理,比如可以分為用戶管理、支付等等的云函數。

  • 云函數
// 函數 user
const TcbRouter = require('tcb-router');

exports.main = async (event, context) => {
    const app = new TcbRouter({ event });
    
    app.router('register', async (ctx, next) => {
        await next();
    }, async (ctx, next) => {
        await next();
    }, async (ctx) => {
        ctx.body = {
            code: 0,
            message: 'register success'
        }
    });

    app.router('login', async (ctx, next) => {
        await next();
    }, async (ctx, next) => {
        await next();
    }, async (ctx) => {
        ctx.body = {
            code: 0,
            message: 'login success'
        }
    });

    return app.serve();
};

// 函數 pay
const TcbRouter = require('tcb-router');

exports.main = async (event, context) => {
    const app = new TcbRouter({ event });
    
    app.router('makeOrder', async (ctx, next) => {
        await next();
    }, async (ctx, next) => {
        await next();
    }, async (ctx) => {
        ctx.body = {
            code: 0,
            message: 'make order success'
        }
    });

    app.router('pay', async (ctx, next) => {
        await next();
    }, async (ctx, next) => {
        await next();
    }, async (ctx) => {
        ctx.body = {
            code: 0,
            message: 'pay success'
        }
    });

    return app.serve();
};
  • 小程序端
// 注冊用戶
wx.cloud.callFunction({
      name: 'user',
      data: {
        $url: 'register',
        name: 'tcb',
        password: '09876'
      }
    }).then((res) => {
      console.log(res);
    }).catch((e) => {
      console.log(e);
});

// 下單商品
wx.cloud.callFunction({
      name: 'pay',
      data: {
        $url: 'makeOrder',
        id: 'xxxx',
        amount: '3'
      }
    }).then((res) => {
      console.log(res);
    }).catch((e) => {
      console.log(e);
});

架構三: 由一個云函數處理所有服務

  • 云函數
// 函數 router
const TcbRouter = require('tcb-router');

exports.main = async (event, context) => {
    const app = new TcbRouter({ event });
    
    app.router('user/register', async (ctx, next) => {
        await next();
    }, async (ctx, next) => {
        await next();
    }, async (ctx) => {
        ctx.body = {
            code: 0,
            message: 'register success'
        }
    });

    app.router('user/login', async (ctx, next) => {
        await next();
    }, async (ctx, next) => {
        await next();
    }, async (ctx) => {
        ctx.body = {
            code: 0,
            message: 'login success'
        }
    });

    app.router('pay/makeOrder', async (ctx, next) => {
        await next();
    }, async (ctx, next) => {
        await next();
    }, async (ctx) => {
        ctx.body = {
            code: 0,
            message: 'make order success'
        }
    });

    app.router('pay/pay', async (ctx, next) => {
        await next();
    }, async (ctx, next) => {
        await next();
    }, async (ctx) => {
        ctx.body = {
            code: 0,
            message: 'pay success'
        }
    });

    return app.serve();
};
  • 小程序端
// 注冊用戶
wx.cloud.callFunction({
      name: 'router',
      data: {
        $url: 'user/register',
        name: 'tcb',
        password: '09876'
      }
    }).then((res) => {
      console.log(res);
    }).catch((e) => {
      console.log(e);
});

// 下單商品
wx.cloud.callFunction({
      name: 'router',
      data: {
        $url: 'pay/makeOrder',
        id: 'xxxx',
        amount: '3'
      }
    }).then((res) => {
      console.log(res);
    }).catch((e) => {
      console.log(e);
});

借鑒 Koa2 的中間件機制實現云函數的路由管理

小程序·云開發的云函數目前更推薦 async/await 的玩法來處理異步操作,因此這里也參考了同樣是基于 async/await 的 Koa2 的中間件實現機制。

從上面的一些例子我們可以看出,主要是通過 use 和 router 兩種方法傳入路由以及相關處理的中間件。

use 只能傳入一個中間件,路由也只能是字符串,通常用于 use 一些所有路由都得使用的中間件

// 不寫路由表示該中間件應用于所有的路由
app.use(async (ctx, next) => {

});

app.use('router', async (ctx, next) => {

});

router 可以傳一個或多個中間件,路由也可以傳入一個或者多個。

app.router('router', async (ctx, next) => {

});

app.router(['router', 'timer'], async (ctx, next) => {
    await next();
}, async (ctx, next) => {
    await next();
}, async (ctx, next) => {

});

不過,無論是 use 還是 router,都只是將路由和中間件信息,通過 _addMiddleware 和 _addRoute 兩個方法,錄入到 _routerMiddlewares 該對象中,用于后續調用 serve 的時候,層層去執行中間件。

最重要的運行中間件邏輯,則是在 serve 和 compose 兩個方法里。

serve 里主要的作用是做路由的匹配以及將中間件組合好之后,通過 compose 進行下一步的操作。比如以下這段節選的代碼,其實是將匹配到的路由的中間件,以及 * 這個通配路由的中間件合并到一起,最后依次執行。

let middlewares = (_routerMiddlewares[url]) ? _routerMiddlewares[url].middlewares : [];
// put * path middlewares on the queue head
if (_routerMiddlewares['*']) {
    middlewares = [].concat(_routerMiddlewares['*'].middlewares, middlewares);
}

組合好中間件后,執行這一段,將中間件 compose 后并返回一個函數,傳入上下文 this 后,最后將 this.body 的值 resolve,即一般在最后一個中間件里,通過對 ctx.body 的賦值,實現云函數的對小程序端的返回:

const fn = compose(middlewares);

return new Promise((resolve, reject) => {
    fn(this).then((res) => {
        resolve(this.body);
    }).catch(reject);
});

那么 compose 是怎么組合好這些中間件的呢?這里截取部份代碼進行分析

function compose(middleware) {
    /**
     * ... 其它代碼 
     */
    return function (context, next) {
        // 這里的 next,如果是在主流程里,一般 next 都是空。
        let index = -1;

        // 在這里開始處理處理第一個中間件
        return dispatch(0);

        // dispatch 是核心的方法,通過不斷地調用 dispatch 來處理所有的中間件
        function dispatch(i) {
            if (i <= index) {
                return Promise.reject(new Error('next() called multiple times'));
            }

            index = i;

            // 獲取中間件函數
            let handler = middleware[i];

            // 處理完最后一個中間件,返回 Proimse.resolve
            if (i === middleware.length) {
                handler = next;
            }

            if (!handler) {
                return Promise.resolve();
            }

            try {
                // 在這里不斷地調用 dispatch, 同時增加 i 的數值處理中間件
                return Promise.resolve(handler(context, dispatch.bind(null, i + 1)));
            }
            catch (err) {
                return Promise.reject(err);
            }
        }
    }
}

看完這里的代碼,其實有點疑惑,怎么通過 Promise.resolve(handler(xxxx)) 這樣的代碼邏輯可以推進中間件的調用呢?

首先,我們知道,handler 其實就是一個 async function,next,就是 dispatch.bind(null, i + 1) 比如這個:

async (ctx, next) => {
    await next();
}

而我們知道,dispatch 是返回一個 Promise.resolve 或者一個 Promise.reject,因此在 async function 里執行 await next(),就相當于觸發下一個中間件的調用。

當 compose 完成后,還是會返回一個 function (context, next),于是就走到下面這個邏輯,執行 fn 并傳入上下文 this 后,再將在中間件中賦值的 this.body resolve 出來,最終就成為云函數數要返回的值。

const fn = compose(middlewares);

return new Promise((resolve, reject) => {
    fn(this).then((res) => {
        resolve(this.body);
    }).catch(reject);
});

看到 Promise.resolve 一個 async function,許多人都會很困惑。其實撇除 next 這個往下調用中間件的邏輯,我們可以很好地將邏輯簡化成下面這段示例:

let a = async () => {
    console.log(1);
};

let b = async () => {
    console.log(2);

    return 3;
};


let fn = async () => {
    await a();
    return b();
};

Promise.resolve(fn()).then((res) => {
    console.log(res);
});

// 輸出
// 1
// 2
// 3
重磅推薦:小程序開店目錄

第一部分:小商店是什么

第二部分:如何開通一個小商店

第三部分:如何登錄小商店

第四部分:開店任務常見問題

第五部分:小商店可以賣什么

第六部分:HiShop小程序特色功能

第七部分:小程序直播

第八部分:小程序收貨/物流

第九部分:小程序怎么結算

第十部分:小程序客服

第十一部分:電商創業

第十二部分:小程序游戲開發

電話咨詢 微信咨詢 預約演示 0元開店
主站蜘蛛池模板: 午夜影院在线播放|色姑娘天天综合|亚洲=av国产=av综合=av|#NAME?|亚洲毛片一区二区三区|#NAME? | 久久久久无码国产精品一区乞丐|97一区二区三区|成人影院久久|九九九免费|俄罗斯18一19sex性大|国产精品一二三四区免费 | 日本三级精品视频|国产人妻人伦精品无码|国产毛片久久久久久|奇米网首页|亚洲精品久久久打桩机小说|欧美一区二区三区成人 | 强奷乱码欧妇女中文字幕熟女|中国女人FREE性HD|国产精品一码二码三码在线|少妇性l交大片免费快色|久热=av在线|黑人巨大人精品欧美三区 | 美女=av影院|惊弦45集全免费815|日本免费人成视频播放|欧洲一区二区三区精品|亚洲国产精品久久无码中文字|欧美刺激性大交 | 亚洲免费不卡视频|国精产品一品二品国精品69XX|欧美色p|国产成人黄色网址|国产成人无码免费看片软件|欧美一二区在线观看 | 人人射影院|日韩免费一区二区三区高清|欧美狠狠|91精品蜜臀在线一区尤物|国产日本韩国在线|无码人妻精品一区二区三区99仓本 | 国产成人精品777|久久久久国内精品|国产乱妇无乱码大黄=a=a片|久久字幕网|一区二区三区无码高清视频|在线视频综合 | 天天干天天骑|黄色大片免费播放|亚洲精品美女在线观看|伊人看片|日韩欧美伦理片|免费观看91 | www.超碰在线.com|日本在线观看无码不卡V|免费观看日本污污ww网站|一区2区|91福利区|国产精品久久久久久238 | 国产同事露脸对白在线视频|91在线91|国产免费看=av大片的网站吃奶|精品国产鲁一鲁一区二区张丽|国产对白久久|5lⅴ精品国产91久久 | 国产乱人乱精一区二区视频|97性无码区免费|色七七在线|亚洲=aV无码区在线观看东京热|免费看啪啪人=a片=a=a=a片|乱老熟女一区二区三区 | 少妇被粗大的猛烈进出|肥大BBwBBWBBw高潮|日韩中文字幕网址|手机看片国产=aV无码|国产精品一区二区免费看|#NAME? | 美女=aV一区二区三区|九九热久久这里只有精品|国产精品免费不卡|少妇的BBBB爽爽爽自慰|中文字幕乱码久久午夜不卡|天天做日日做天天爽视频免费 | 亚州性色|国产的欧美一区二区三区|中国毛片视频|久久艹在线|国产在线www|久久久精品日韩免费观看 | 久久麻传媒亚洲=av国产|久久久久国产精品麻豆|啪啪伊人网|亚洲精品久中文字幕花红影视|欧美丰满熟妇xxxxx|www.国产一区 | 青青91视频|青娱乐极品视觉盛宴国产视频|宅男在线观看免费高清网站|午夜伦理一区|最新国产在线观看|黄色大片www | 国产成人精品视频一区二区不卡|欧美日韩色另类综合|中文字幕在线欧美|免费视频日韩|国产精品第七十二页|天天草狠狠干 | 精品久久久成人|欧美人与性囗牲恔配|漂亮人妇中出中文字幕在线|91=avpornwwww蝌蚪99|狠狠爱亚洲|久久亚洲一区二区三区四区五区高 | 日韩一级色|亚洲一级成人|亚洲=aV无码专区亚洲=aV桃花岛|91啦在线观看|性高潮久久久久久久|国产美女国产爽字 | 最近中文字幕在线mv视频在线|#NAME?|色惰网站|草逼一区|免费精品国产的网站免费观看|播放日韩一级黄色片 | 精品人妻无码一区二区三区不卡|性欧美视频在线|99九色|99久久精品美女高潮喷水|国产午夜福利在线看|国产免费黄网 | 人人精品久久|无码=aV潮喷|国产小视频国产精品|18深夜在线观看免费视频|好久被狂躁=a片视频无码免费视频|国产一级淫片=a免费播放鬼片 | 中文字幕一级毛片|538精品视频在线|www亚洲|白丝=av片|网友自拍=av|男人边吻奶边挵进去视频 | 亚洲精品久久国产精品|亚洲三区精品|麻豆精产一二三产区|午夜嫩草嘿嘿福利777777|亚洲日本久久|亚洲中文无码永久免弗 | 国产一区二区三区精品久久久|欧美午夜一区二区|久草新免费|91=av成人|男人午夜在线|亚洲欧美国产vr在线观 | 国产亚洲综合日韩一区|亚洲成人一区二区三区在线观看|亚洲精品日本久久一区二区三区|国产91=av视频在线观看|97色在线观看|精品国产香蕉伊思人在线 | 黄色国产毛片|成年人啪啪|午夜影院免费观看视频|久久免费精品国自产拍网站|成人免费=a级毛片韩国|www.伊人网 | 7777欧美成是人在线观看|无码=aV中文一区二区三区桃花岛|日本精品久久久久久久久久|一级做=a爰片|成人综合一区二区|99热热精品 | 国产乱码一区二区三区|久久婷婷麻豆国产91天堂|无毛一区二区|日韩久久综合|午夜影院福利社|日韩字幕一区 | 大地免费资源|成人综合色区|无码综合天天久久综合网|男人猛躁女人网站|国产午夜福利小视频合集|国产女人与公拘交在线播放 | 在线看免费观看=av|十九岁大学生日本在线播放|91在线看视频|欧美日韩国产综合新一区|韩日黄色毛片|刘亦菲精品国产亚洲人成 | 精品国产96亚洲一区二区三区|水蜜桃综合久久无码欧美|国产精品久久久久久久第一福利|成人无码免费视频在线观看网址|伊人wwwyiren22cn|极品尤物被啪到呻吟喷水 | 亚洲αv久久久噜噜噜噜噜|国产乱码精品一区二区三|哈哈操影院|#NAME?|国产看片网址导航|欧美V亚洲V日韩V最新在线 | 欧美精选午夜久久久乱码6080|97人妻无码专区|日韩性生活视频|成人超碰|台湾全黄色裸体视频播放|黄色大片视频在线观看 | 亚洲午夜久久久综合37日本|欧美高潮抽搐喷水大叫|啪一啪鲁一鲁|亚洲欧洲美洲无码精品V=a|亚洲高清视频网站|三级黄色影院 | 14美女爱做视频免费|合之合合综合久|99在线热视频|#NAME?|午夜视频网|韩剧网韩剧TV在线观看 | 91精品国产综合久久香蕉最新版|久久97久久|国产福利三区|华人在线视频|mm1313美女视频|一区二区免费播放 | 1级黄色毛片|福利久久久|欧美又爽又大又黄=a片|国产精品拍自在线|中文字幕在线观看亚洲|国产日韩视频在线 | 97porm国内自拍视频|午夜精品一区二区三区在线播放|久久免费手机视频|人妻体体内射精一区二区|一级片=a|日本亚洲中文在线 | 毛片免费全部播放无码私人|夜夜爽狠狠澡97欧美精品|日韩中文一区二区三区|欧美孕交videosfree黑人巨大|丰满少妇女人=a毛片视频|国产SUV精品一区二区 |