前端筆記之React(六)ES6的Set和Map&immutable和Ramda和lodash&redux-thunk

来源:https://www.cnblogs.com/rope/archive/2019/08/02/10741659.html
-Advertisement-
Play Games

一、ES6的Set、Map數據結構 Map、Set都是ES6新的數據結構,都是新的內置構造函數,也就是說typeof的結果,多了兩個: Set 是不能重覆的數組 Map 是可以任何東西當做鍵的對象 ES6 提供了新的數據結構 Set。它類似於數組,但是成員的值都是唯一的,沒有重覆的值。 let s ...


一、ES6SetMap數據結構

MapSet都是ES6新的數據結構,都是新的內置構造函數,也就是說typeof的結果,多了兩個:

Set 是不能重覆的數組

Map 是可以任何東西當做鍵的對象

 

ES6 提供了新的數據結構 Set。它類似於數組,但是成員的值都是唯一的,沒有重覆的值。

let s = new Set();
s.add(1);
s.add(2);
s.add(3);
s.add(3);
s.add(3);
s.add(4);
s.add(5);
console.log(s)
示例代碼

 

 

 

集合中添加數據用add()方法,會自動過濾已經有的元素。

 

最快的數組去重方法:

let s = new Set([1,2,3,3,3,4,5]);
console.log([...s])

let s = new Set([1,2,3,4,5]);
console.log(s.size)
console.log(s.has(5))
console.log(s.delete(5))
console.log(s)
示例代碼

 

集合的關註點是在元素裡面,而不關註順序,所以不提供s[0]來枚舉某項API,但是可以轉為數組[...s]

 

JavaScript 的對象(Object),本質上是鍵值對的集合(Hash 結構),但是傳統上只能用字元串當作鍵。這給它的使用帶來了很大的限制。

為瞭解決這個問題,ES6 提供了 Map 數據結構。它類似於對象,也是鍵值對的集合,但是“鍵”的範圍不限於字元串,各種類型的值(包括對象)都可以當作鍵。也就是說,Object 結構提供了“字元串—值”的對應,Map 結構提供了“值—值”的對應,是一種更完善的 Hash 結構實現。如果你需要“鍵值對”的數據結構,Map Object 更合適。

let m = new Map();
const o = {a:1,b:2};
m.set("haha", 123);
m.set(o, 456)
m.set(888,789)
console.log(m)
console.log(m.get(o))
示例代碼

 

 

 

使用get()來得到元素的值,key是區分類型的。


二、函數式編程庫

所謂的“函數式編程”指的是程式中的函數的是“純函數”,就表示一個函數不改變傳入的參數。

我們之前大量使用...filtermap等等操作,略微麻煩,就有3個特別好用的函數式編程庫應運而生。

2.1 immutable.js

2.1.1概述

來自Facebook,是官方推薦的庫,immutable表示不可變。immutable總是返回新的對象,不會修改原對象。

 

immutable不是深拷貝對象,創造性的使用DIFF演算法,有一個結構共用機制,它所做的是智能分析改變,讓改變後的元素可以共用改變之前的一些結構。

Immutable 使用了 Structural Sharing(結構共用),即如果對象樹中一個節點發生變化,只修改這個節點和受它影響的父節點,其它節點則進行共用。

{
    a:{"x":1 , "y":2},
    b:{
        c:{"x":3, "y":4},
        d:{"x":5},
    }
}
{
    a:{"x":1 , "y":2},
    b:{
        c:{"x":8, "y":4},
        d:{"x":5},
    }
}

上面代碼中,顏色相同部分,還是記憶體中同一個對象。


2.1.2基本講解

官方:http://facebook.github.io/immutable-js/docs/#/

安裝依賴:

npm install immutable --save

immutable提供了兩個數據類型:

ListMapimmutable自己封裝的一個類,List是不可變的數組,Map是不可變的對象。

 

fromJS() 將一個原生js數據類型轉換為immutable類型的數據

toJS()   將一個immutable類型的數據轉換為JS類型的數據。

List()Map() 用來創建新的ListMap對象(將原生JS對象和數組轉換到不可變的MapList

 

immutable思維:

先用fromJS()List()Map()將原生JS的數組、對象、變為ListMap對象

然後再操作,比如對數組的push操作

最後.toJS()immutable對象變為原生JS的數組、對象

 

Nodejs環境中引包:

var immutable = require("immutable");
var List = immutable.List

const list1 = List(["白板","么雞","三條","三萬"])
const list2 = list1.push("四條")
console.log(list1.toJS())
console.log(list2.toJS())

會發現push之後,原數組沒有改變,只返回了新數組。

上面案例是用List(原數組)將數組變為List對象,也可以用fromJS

 

var immutable = require("immutable");
var fromJS = immutable.fromJS

const list1 = fromJS(["白板","么雞","三條","三萬"])
const list2 = list1.push("四條")
console.log(list1.toJS())
console.log(list2.toJS())

 

數組的頭尾操作,也不會改變原數組,都是返回新數組:

var immutable = require("immutable");
var fromJS = immutable.fromJS

const list1 = fromJS(["白板","么雞","三條","三萬"])
const list2 = list1.push("四條")
const list3 = list1.pop()
const list4 = list1.unshift("東風")
const list5 = list1.shift()

console.log(list1.toJS())
console.log(list2.toJS())
console.log(list3.toJS())
console.log(list4.toJS())
console.log(list5.toJS())
示例代碼

 

更改set

set表示更改下標為2的項為“二筒”,註意不會真的改變原數組,而是返回新數組:

const list1 = fromJS(["白板","么雞","三條","三萬"])
const list2 = list1.set(2,"二筒");

 

對象也有set

const obj1 = fromJS({"a" : 1, "b" : 2 ,"c" : 3})
const obj2 = obj1.set("b",888)

console.log(obj1.toJS())
console.log(obj2.toJS())

 

在數組中查找某一項,使用find(),尋找某一項下標用findIndex()

得到Map對象的某一個鍵的值,要用get()方法

var immutable = require("immutable");
var fromJS = immutable.fromJS

const data = fromJS([
    {"id" : 1, "name" : "小明", "age" : 12},
    {"id" : 2, "name" : "小紅", "age" : 12},
    {"id" : 3, "name" : "小強", "age" : 13},
])

const item = data.find(item=>item.get("id") == 2);
console.log(item.toJS())

 

刪除用delete,刪除下標為2的項

const list1 = fromJS([111,222,333,888,999]);
const list2 = list1.delete(2);
console.log(list1.toJS());
console.log(list2.toJS());

 

is()函數驗證是否相等

var {is , Map} = require("immutable");
let o1 = Map({a : 1, b : 2, c : 3});
let o2 = Map({a : 1, b : 2, c : 3});

console.log(o1 == o2);  //在記憶體中不相等
console.log(is(o1,o2)); //在immutable世界中是相等


2.1.3真實項目場景

真實項目場景 - 增加todo,用set設置,用get獲取

var immutable = require("immutable");
var fromJS = immutable.fromJS

const data = fromJS({
    "todos" : [
        {"id" : 1,"title" : "吃飯", "done" : false },
        {"id" : 2,"title" : "睡覺", "done" : false },
        {"id" : 3,"title" : "打豆豆", "done" : false },
    ],
    "show" : "ALL"
})

const newData = data.set(
    "todos",
    data.get("todos").push({"id" : 4,"title" : "打架", "done" : false})
)
console.log(newData.toJS())

 

真實項目場景 - 刪除id2todo,使用delete(2)

//刪除id為2的項
const newdata = data.set(
"todos", 
data.get("todos").delete(data.get("todos").findIndex(item=>item.get("id")== 2)
));

console.log(newdata.toJS());

 

方法2

const newData = data.set(
    "todos",
    data.get("todos").filter(item=>item.get("id") != 2)
)

 

真實項目場景 - 改變id2的項title為“吃雞”

方法1

var index = data.get("todos").findIndex(item=>item.get("id") == 2);
var item = data.get("todos").get(index)
const newData = data.set("todos",data.get("todos").set(index, item.set("title","吃雞")));

console.log(newData.toJS())

 

方法2

const newData = data.set("todos",data.get("todos").map(item=>{
    return item.get("id") == 2 ? item.set("title" , "吃雞") : item;
}))


2.1.4redux結合

改造TodoList項目:

只改變reducers中的文件夾的寫法,其它地方一律不改。

state的數據依然是原生JS的數組和對象,只不過在reducer函數運行中,瞬間變成為immutableListMap了,但是出去的時候就toJS了,裡外里,state還是原生數組、對象。

import {fromJS , toJS} from "immutable";
const initObj = {
    "todos" : [
        {"id" : 1 , "title" : "吃飯" , "done" : false},
        {"id" : 2 , "title" : "睡覺" , "done" : true},
        {"id" : 3 , "title" : "打豆豆" , "done" : true}
    ],
    "show" : "ALL"         
}

export default (state = initObj, action) => {
    //下麵的語句很重要,變為immutable對象
    state = fromJS(state);

    if(action.type == "ADDTODO"){
         return state.set("todos", state.get("todos").push(
             {
                 "id" : state.get("todos").reduce((a,b)=>{
          return b.get("id") > a ? b.get("id") : a
          }, 0) + 1,
                 "title" : action.title,
                 "done" : false
             }
         )).toJS();
    }else if(action.type == "DELTODO"){
        return state.set(
"todos", 
state.get("todos").filter(item=>item.get("id") != action.id)
).toJS();
    }else if(action.type == "CHANGETODO"){
        return state.set(
"todos", 
state.get("todos").map(
item => item.get("id") == action.id ? item.set(action.k, action.v) : item
)
).toJS();
    }else if(action.type == "CHANGESHOW"){
        return state.set("show", action.show).toJS();
    }
    return state.toJS();
}

2.2 Ramda.js

純函數,也叫作“蘭姆達函數”,就是ramda這個詞。http://ramda.cn/

2.2.1函數柯里化基礎

函數柯里化(Currying),是把接受多個參數的函數變換成接受一個單一參數的函數,並且返回接受餘下的參數,而且返回結果的新函數。柯里化函數就是逐步傳參,逐步縮小函數的適用範圍,逐步求解的過程。

 

簡單的加法函數:

function add(x,y){
    return x + y;
}
add(2,3);//5

如果用函數柯里化接受兩個參數的函數變成單一參數,如下:

function add(x) {
    return function (y){
        return x + y
    }
}

console.log(add(2)(3))
示例代碼

 


 

2.2.2基本講解

npm install ramda --save

數組尾插一項:

var R = require("ramda");

var arr1 = ["紅中","白板","么雞"];
var arr2 = R.append("一筒", arr1)
var arr3 = R.append("二筒")(arr1)

console.log(arr1)
console.log(arr2)
console.log(arr3)

被操作的元素放到最後一個參數。

 

 

數組頭插一項:

var R = require("ramda");

var arr1 = ["紅中","白板","么雞"];
var arr4 = R.prepend("發財",arr1)

console.log(arr4)
示例代碼

 

 

 


2.2.3真實項目場景

改變對象的b屬性為8

這裡使用了非常重要的方法R.lensProp()聚焦到某屬性,功能就是讓改變的值從原基礎上進行修改

var R = require("ramda");

const obj1 = {"a" : 1,"b" : 2,"c" : 3}
const obj2 = R.set(R.lensProp("b") , 8, obj1)
console.log(obj2)

 

刪除id2的項:

const state = {
    "todos": [
       {"id" : 1, "title" : "吃飯",  "done" : false},
       {"id" : 2, "title" : "睡覺",  "done" : false},
       {"id" : 3, "title" : "打豆豆","done" : false}
    ],
    "show":"ALL"
}

//刪除id為2的項
const newstate = R.set(R.lensProp("todos"), R.filter(item=>item.id != 2, state.todos) , state);
console.log(newdata)

 

修改id2的項title為吃雞

const newstate = R.set(R.lensProp("todos"),R.map(item => item.id == 2 ? 
R.set(R.lensProp("title"),"吃雞",item) : item , state.todos), state);

 

修改showONLYDONE

const newstate = R.set(R.lensProp("show") , "ONLYDONE", state);

基本上一條語句能夠解決問題,不再寫...了,並且相比如immutable,沒有MapList和對象、數組的轉換。


2.2.4redux結合

還是用todolist舉例,在reducers/index.js中修改,下麵標黃色的語句的R.__是占位符:

var R = require("ramda");

const initObj = {
    "todos" : [
        {"id" : 1 , "title" : "吃飯" , "done" : false},
        {"id" : 2 , "title" : "睡覺" , "done" : true},
        {"id" : 3 , "title" : "打豆豆", "done" : true}
    ],
    "show" : "ALL"         
}

export default (state = initObj, action) => {
//R.__表示占位符,下麵調用setTodos時,就等於傳入了要更改成為的值
    const setTodos = R.set(R.lensProp("todos"), R.__ , state);
    const setShow  = R.set(R.lensProp("show") , R.__ , state);

    if(action.type == "ADDTODO"){
        return setTodos(R.append({
            "id" : state.todos.reduce((a,b) => b.id > a ? b.id : a, 0) + 1,
            "title" : action.title,
            "done" : false
        },state.todos));
    }else if(action.type == "DELTODO"){
        return setTodos(state.todos.filter(item=>item.id != action.id));
    }else if(action.type == "CHANGETODO"){
        return setTodos(state.todos.map(item=>item.id == action.id ? R.set(R.lensProp(action.k), action.v, item) : item))
    }else if(action.type == "CHANGESHOW"){
        return setShow(action.show);
    }
    return state;
}

2.3 lodash.js

2.3.1基本講解

實際上underscore.js已經在“函數庫工具”輸給了lodashlodash完全可以替代underscore

官網:https://lodash.com/

中文:https://www.lodashjs.com/

中文:http://www.css88.com/doc/lodash/

npm install --save lodash

 

underscore有的函數,lodash全有,比如數組去重和最大最小值:

var _ = require("lodash");

var arr1 = [3,3,3,3,4,4,4,4,5,5,5,5,3];
var arr2 = _.uniq(arr1);

console.log(arr1);
console.log(arr2);

console.log(_.max(arr1));
console.log(_.min(arr1));

 

lodash中有子包,叫做fpfpfunctional programing函數式編程的意思。

需要引入這個包

var fp = require("lodash/fp");

更改b屬性為8

var fp = require("lodash/fp");

var obj1 = {"a" : 1 , "b" : 2 , "c" : 3};
var obj2 = fp.set("b" , 8 , obj1);

console.log(obj1);
console.log(obj2);
示例代碼

 

 

 

和ramda一樣,被操作對象寫最後一個參數。


2.3.2真實項目場景

刪除

var fp = require("lodash/fp");

const state = {
    "todos" : [
        {"id" : 1 , "title" : "吃1飯" , "done" : false},
        {"id" : 2 , "title" : "吃2飯" , "done" : false},
        {"id" : 3 , "title" : "吃3飯" , "done" : false}
    ],
    "show" : "ALL"
};

//刪除id為2的項
const newstate = fp.set("todos", state.todos.filter(item => item.id != 2), state);

console.log(state);
console.log(newstate);

 

增加:

const newstate = fp.set("todos", fp.concat(
    state.todos,
    {
        "id" : state.todos.reduce((a,b) => b.id > a ? b.id : a, 0) + 1,
        "title": "吃雞",
        "done" : false
    }
) , state);

 

修改id2的項的title為“吃雞”

const newstate = fp.set("todos",state.todos.map(item=>item.id == 2 ? fp.set("title", "吃雞", item) : item), state);

如果遇見比較難的場景,此時可以用克隆方法,比如在第2項之間插入一項

const _todos = fp.clone(state.todos)

//更改克隆之後的數組
_todos.splice(2,0,{"id": 4,"title":"游泳","done":false})

//更改state
const newstate = fp.set("todos", _todos, state)
console.log(state)
console.log(newstate)
示例代碼
const car = {
    "cars" : {
        "a" : [
            {
                "name" : "奧迪" ,
                "series" : [
                    {
                        "name" : "A6",
                        "type" : "豪華轎車"
                    },
                    {
                        "name" : "A4",
                        "type" : "豪華轎車"
                    }
                ]
            },
            {
                "name" : "奧拓",
                "series" : [{"奧拓1號" : 2}]
            }
        ],
        "b" : [
            {"賓士" : 1}
        ]
    }
}

//改變A6的車係為普通轎車
var newstate = fp.cloneDeep(car);
newstate.cars.a[0].series[0].type = '普通轎車';

console.log(JSON.stringify(newstate))
示例代碼

2.3.3 redux結合

import fp from "lodash/fp"; 

const initObj = {
    "todos" : [
        {"id" : 1 , "title" : "吃飯" , "done" : false},
        {"id" : 2 , "title" : "睡覺" , "done" : true},
        {"id" : 3 , "title" : "打豆豆" , "done" : true}
    ],
    "show" : "ALL"         
}

export default (state = initObj, action) => {
    if(action.type == "ADDTODO"){
        return fp.set("todos" , fp.concat(state.todos , {
            "id" : state.todos.reduce((a,b) => b.id > a ? b.id : a , 0) + 1,
            "title" : action.title,
            "done" : false
        }), state);
    }else if(action.type == "DELTODO"){
        return fp.set("todos" , state.todos.filter(item => item.id != action.id) , state);
    }else if(action.type == "CHANGETODO"){
        return fp.set("todos", state.todos.map(item=>item.id == action.id ? fp.set(action.k,action.v,item) : item) , state);
    }else if(action.type == "CHANGESHOW"){
        return fp.set("show" , action.show , state);
    }
    return state;
}

三、非同步

3.1搭建伺服器

我們將所有前端的東西都放入www文件夾中。

 

Node.jsapp.js實現數據介面:

var express = require("express");
var app = express();
app.use(express.static("www"))

app.get("/api",(req,res)=>{
    res.json({"result":8})
})
app.listen(3000);
示例代碼

3.2 redux-thunk解決非同步

我們現在有四個文件都沒有地方適合寫非同步:componentsactionsconstantsreducer

所以React提供了react-thunk包,thunk是中間件,所謂的中間件就是在發出actionreducer進行改變的中間,要做的事。

https://www.npmjs.com/package/redux-thunk

 

安裝依賴:

npm install --save redux-thunk

main.js

import React from "react";
import ReactDOM from "react-dom";
import { createStore, applyMiddleware} from "redux";
import { Provider } from 'react-redux'
import thunk from 'redux-thunk' 
import reducers from "./reducers/index";
import logger from "redux-logger";
//引入父組件
import App from "./containers/App";

//創建Redux store 倉庫用來存放狀態
const store = createStore(reducers, applyMiddleware(logger, thunk))

ReactDOM.render(
    <Provider store={store}>
        <App></App>
    </Provider>,
    document.getElementById('app')
)

 

components/counter/index.js組件,按鈕點擊之後做addServer

<button onClick={()=>{this.props.counterActions.addServer()}}>加伺服器那麼多</button>

 

此時actions/counterActions.js文件中,就可以寫非同步函數了:

兩步:第一步請求伺服器數據,第二步發出action。將伺服器的返回結果,當做載荷發給reducer

import {ADD , MINUS , ADDSERVER} from "../constants/COUNTER.js";

//同步陣營,直接返回一個Action
export const add = () => ({"type" : ADD});
export const minus = () => ({"type" : MINUS});

//非同步有兩個(),第一個()接受按鈕傳的參數,第二個()是系統給你的dispatch和getState
//export const addServer = (n)=> (dispatch, getState)=>{ 
//    alert(n) 
//    alert(dispatch)
//    alert(getState().counter.v)
//}

export const addServer = ()=> async (dispatch , getState) => {
    //發出Ajax請求,實際上是fetch請求,fetch不是Ajax
    const {result} = await fetch("/api").then(data=>data.json());
    //發action,因為唯一能改變reducer的方法就是dispath一個action
    dispatch({"type" : ADDSERVER , result})
}

 

constants/COUNTER.js

export const ADDSERVER = "ADDSERVER_COUNTER";

reducers/counter.js

import {ADD , MINUS , ADDSERVER} from "../constants/COUNTER.js";
export default (state = {"v" : 0} , action) => {
    if(action.type == ADD){
        ...
    }else if(action.type == MINUS){
        ...
    }else if(action.type == ADDSERVER){
        	   

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在早期編寫JavaScript時,我們只需在<script>標簽內寫入JavaScript的代碼就可以滿足我們對頁面交互的需要了。但隨著時間的推移,時代的發展,原本的那種簡單粗暴的編寫方式所帶來的諸如邏輯混亂,頁面複雜,可維護性差,全局變數暴露等問題接踵而至,前輩們為瞭解決這些問題提出了很種的解決方 ...
  • 一、redux-saga解決非同步 redux-thunk 和 redux-saga 使用redux它們是必選的,二選一,它們兩個都可以很好的實現一些複雜情況下redux,本質都是為瞭解決非同步action而生,使redux保持完整性,不至於太過混亂。redux-saga 是一個用於管理Redux 應用 ...
  • 因為項目需求,最近開始轉到微信公眾號開發,接觸到了Vue框架,這個效果的實現雖說是基於Vue框架下實現的,但是同樣也可以借鑒到其他地方,原理都是一樣的。 進入正題,先看下效果圖: 其實js做這個效果還是挺簡單的,因為在css中我們可以設置一個元素的position: fixed;,這樣它就可以固定在 ...
  • 本例結合我的前兩篇博客,使用jquery moblie框架搭建了一個簡單的手機版博客園;項目地址為http://blog.mdzz.tv:1011,這裡我僅爬取了博客園首頁的鏈接,點擊每一項即跳轉到博客園相應的頁面,源碼已放在github上了,地址https://github.com/guasses... ...
  • 本實例原始信息: 作者: "anix" 演示地址: "Echarts模擬遷徙" 源碼地址: "GitHub ananix qianxi" 前言 “百度地圖春節人口遷徙大數據”(簡稱“百度遷徙”)是百度在春運期間推出的技術品牌項目,為業界首個以“人群遷徙”為主題的大數據可視化項目。 準備 開發工具 由 ...
  • 1.HTML部分 accept屬性可以設置要上傳文件的格式 2.js部分 介面部分 代碼部分 ...
  • 截取字元串中的數字 1、使用parseInt() 2、使用正則 截取字元串 1、使用split() 2、使用join() 3、使用substring() 4、使用indexOf() 5、使用substr() ...
  • 事件處理程式指的是當 HTML 中發生某些事件時所調用的方法,是 jQuery 中的核心函數。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...