ES6 Promise --回調與Promise的對比、信任問題、錯誤處理、Promise的狀態、以及Promise對象的常用方法

来源:https://www.cnblogs.com/chenyingying0/archive/2020/03/27/12578285.html
-Advertisement-
Play Games

之前怎麼用回調解決非同步的問題: function f(callback){ setTimeout(function(){ callback && callback(); }); } f(function(){ console.log(1); f(function(){ console.log(2); ...


之前怎麼用回調解決非同步的問題:

function f(callback){
    setTimeout(function(){
        callback && callback();
    });    
}

f(function(){
    console.log(1);
    f(function(){
        console.log(2);    
        f(function(){
            console.log(3);    
            f(function(){
                console.log(4);    
                f(function(){
                    console.log(5);    
                    f(function(){
                        console.log(6);        
                    })    
                })        
            })    
        })    
    })
})

 

使用promise實現相同的效果

//使用promise實現相同的效果
function f2(){
    return new Promise(resolve=>{//參數傳入一個回調函數
        setTimeout(function(){
            //時執行函數
            resolve();
        },1000)
    })
}

f2()//只有返回Promise實例,才能.then
.then(function(){
    console.log(11);
    return f2();
})
.then(function(){
    console.log(22);
    return f2();
})
.then(function(){
    console.log(33);
    return f2();
})
.then(function(){
    console.log(44);
    return f2();
})
.then(function(){
    console.log(55);
    return f2();
})
.then(function(){
    console.log(66);
    return f2();
})

 

 

對比回調與Promise的流程式控制制

首先是回調

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>index</title>
    <style>
        .box{
            width:100px;
            height:100px;
            background:lightgreen;
            transition:all 1s;
            color:#fff;
            text-align:center;
            line-height:100px;
            font-size:40px;
        }
    </style>
</head>
<body>

    <div class="box">哦</div>
    <button id="btn">開始</button>
<script>
//動畫
function move(el,x,y,cb){
    el.style.transform=`translate(${ x }px, ${ y }px)`;
    setTimeout(function(){
        cb && cb();
    },1000);    
}

//獲取元素
let box=document.querySelector(".box");
let btn=document.querySelector("#btn");
//綁定事件
btn.addEventListener("click",e=>{
    //使用回調完成動畫
    move(box,100,100,function(){
        move(box,200,200,function(){
            move(box,100,300,function(){
                move(box,0,0,function(){
                    console.log("移動結束!");
                })
            })    
        })    
    })    
})

</script>
</body>
</html>

實現的效果

 

使用Promise來實現

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>index</title>
    <style>
        .box{
            width:100px;
            height:100px;
            background:lightgreen;
            transition:all 1s;
            color:#fff;
            text-align:center;
            line-height:100px;
            font-size:40px;
        }
    </style>
</head>
<body>

    <div class="box">哦</div>
    <button id="btn">開始</button>
<script>
//動畫
function move(el,x,y){
    return new Promise(resolve=>{
        el.style.transform=`translate(${ x }px, ${ y }px)`;
        setTimeout(function(){
            resolve();
        },1000);
    })        
}

//獲取元素
let box=document.querySelector(".box");
let btn=document.querySelector("#btn");
//綁定事件
btn.addEventListener("click",e=>{
    //使用Promise完成動畫
    move(box,100,100)
    .then(function(){        
        return move(box,200,200);
    })
    .then(function(){        
        return move(box,100,300);
    })
    .then(function(){        
        return move(box,0,0);
    })
    .then(function(){
        console.log("移動結束!");
    })
})

</script>
</body>
</html>

 

實現一個圖片的載入;設置第一張圖片載入1s之後載入第二張圖片

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>index</title>
    <style>
        img{width:200px;}
    </style>
</head>
<body>


<script>

//設置一個函數,把圖片的url地址作為參數
function createImg(url){
    //實例化promise對象
    return new Promise(resolve=>{
        let img=new Image();//建立圖像對象
        img.src=url;//設置圖片的地址
        document.body.appendChild(img);//把圖片節點插入到body中
        setTimeout(function(){
            resolve();//圖片載入完成後執行resolve 
        },1000);
    })
}

createImg("1.jpg")
.then(function(){
    return createImg("2.jpg")
})
.then(function(){
    return createImg("3.jpg")
});

</script>
</body>
</html>

信任問題

//信任問題演示

//回調
function method(cb){
    setTimeout(function(){
        cb && cb();
        //因為某些bug導致某個函數多執行了一次
        cb && cb();
    },1000);
}

//promise
function method2(){
    return new Promise(resolve=>{
        setTimeout(function(){
            resolve();
            //resolve成功調用一次之後,後面的不會再執行
            resolve();
        },1000);        
    })
}

 

控制反轉

//回調
function method(cb){
    setTimeout(function(){
        cb && cb.call({a:1,b:2});//執行回調,但是添油加醋
    },1000);
}

//promise
function method2(){
    return new Promise(resolve=>{
        setTimeout(function(){
            resolve();//調用的resolve都是自己寫的,改善了控制反轉的問題
        },1000);        
    })
}

 

錯誤處理

function fn(val){
    //第二個參數代表失敗時做的事情
    return new Promise((resolve,reject)=>{
        if(val){
            resolve();
        }else{
            reject();
        }
    })
}

fn(false)
.then(()=>{
    console.log("成功");
},()=>{
    console.log("失敗");
})

 

 

錯誤處理回調可以傳入參數

function fn(val){
    //第二個參數代表失敗時做的事情
    return new Promise((resolve,reject)=>{
        if(val){
            resolve();
        }else{
            reject("404");
        }
    })
}

fn(false)
.then(()=>{
    console.log("成功");
},e=>{
    console.log(e);
})

 

 

resolve也可以傳遞參數,但是只能傳一個,不能傳兩個

function fn(val){
    //第二個參數代表失敗時做的事情
    return new Promise((resolve,reject)=>{
        if(val){
            resolve({a:1},{b:2});
        }else{
            reject("404");
        }
    })
}

fn(true)
.then((obj1,obj2)=>{
    console.log(obj1);
    console.log(obj2);
},e=>{
    console.log(e);
})

 

 

使用實例的catch方法,可以捕獲錯誤

如果返回的是錯誤,則下麵必須有對錯誤的捕獲處理,否則代碼不會執行,會被跳過

function fn(val){
    //第二個參數代表失敗時做的事情
    return new Promise((resolve,reject)=>{
        if(val){
            resolve("這是數據");
        }else{
            reject("404");
        }
    })
}

fn(true)
.then(data=>{
    console.log(data);
    return fn(false);//失敗,拋出錯誤
})
.then(()=>{
    console.log("這裡沒有對錯誤的處理,因此不會執行");
})
.catch(e=>{//捕獲錯誤,執行代碼
    console.log(e);
})

 

 

如果在捕獲錯誤之前,存在對錯誤的處理,那麼catch不會再執行

function fn(val){
    //第二個參數代表失敗時做的事情
    return new Promise((resolve,reject)=>{
        if(val){
            resolve("這是數據");
        }else{
            reject("404");
        }
    })
}

fn(true)
.then(data=>{
    console.log(data);
    return fn(false);//失敗,拋出錯誤
})
.then(()=>{
    console.log("這裡沒有對錯誤的處理,因此不會執行");
})
.then(()=>{
    
},e=>{
    console.log("這裡對錯誤進行了處理,下麵的catch不會被執行了");
})
.catch(e=>{//捕獲錯誤,執行代碼
    console.log(e);
})

 

 

catch之後還可以繼續then,如果再次拋出錯誤,也需要在之後進行錯誤處理

function fn(val){
    //第二個參數代表失敗時做的事情
    return new Promise((resolve,reject)=>{
        if(val){
            resolve("這是數據");
        }else{
            reject("404");
        }
    })
}

fn(true)
.then(data=>{
    console.log(data);
    return fn(false);//失敗,拋出錯誤
})
.then(()=>{
    console.log("這裡沒有對錯誤的處理,因此不會執行");
})
.catch(e=>{//捕獲錯誤,執行代碼
    console.log(e);
    return fn(false);//再次拋出錯誤
});

最後拋出的錯誤沒有捕獲,因此報錯

 

 

 

finally 不管成功或失敗,都會執行

function fn(val){
    //第二個參數代表失敗時做的事情
    return new Promise((resolve,reject)=>{
        if(val){
            resolve("這是數據");
        }else{
            reject("404");
        }
    })
}

fn(true)
.then(data=>{
    console.log(data);
    return fn(false);//失敗,拋出錯誤
})
.catch(e=>{//捕獲錯誤,執行代碼
    console.log(e);
})
.finally(()=>{
    console.log("finally執行一些收尾工作");
})

 

Promise的狀態

panding 進行中

fulfilled 成功

reject 失敗

 

 

Promise.all()

把多個promise實例,包裝成一個新的promise實例

如果所有promise結果都是成功,則返回成功,所有promise返回的數據以數組形式統一返回,且順序一一對應

如果有一個promise決議為失敗,則返回失敗,且把失敗的信息返回

如果是空數組,則立即決議為成功

//模擬需要多個請求數據才能進行下一步的情況
function data1(){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            console.log("data1載入成功");
            resolve("data1");//傳遞參數
        },1000)
    })
}

function data2(){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            console.log("data2載入成功");
            resolve("data2");//傳遞參數
        },1000)
    })
}    

function data3(){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            console.log("data3載入成功");
            resolve("data3");//傳遞參數
        },1000)
    })
}    

function data4(){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            console.log("data4載入成功");
            resolve("data4");//傳遞參數
        },2000)
    })
}    

//全部成功的情況
let res=Promise.all([data1(),data2(),data3(),data4()]);
res
.then(data=>{
    console.log(data);//接收上面傳遞過來的所有參數
})

 

 

//模擬需要多個請求數據才能進行下一步的情況
function data1(){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            console.log("data1載入成功");
            resolve("data1");//傳遞參數
        },1000)
    })
}

function data2(){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            reject("data2 err");//數據2請求失敗
        },1000)
    })
}    

function data3(){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            console.log("data3載入成功");
            resolve("data3");//傳遞參數
        },1000)
    })
}    

function data4(){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            console.log("data4載入成功");
            resolve("data4");//傳遞參數
        },2000)
    })
}    

//全部成功的情況
let res=Promise.all([data1(),data2(),data3(),data4()]);
res
.then(data=>{
    console.log(data);//接收上面傳遞過來的所有參數
},e=>{
    console.log(e);//有錯誤執行這句並立刻返回錯誤信息,正確的數據不會返回
})

 

 

//模擬需要多個請求數據才能進行下一步的情況
function data1(){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            console.log("data1載入成功");
            resolve("data1");//傳遞參數
        },1000)
    })
}

function data2(){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            reject("data2 err");//數據2請求失敗
        },1000)
    })
}    

function data3(){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            console.log("data3載入成功");
            resolve("data3");//傳遞參數
        },1000)
    })
}    

function data4(){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            console.log("data4載入成功");
            resolve("data4");//傳遞參數
        },2000)
    })
}    

//全部成功的情況
let res=Promise.all([]);
res
.then(()=>{
    console.log("決議成功");//空數組直接決議為成功
},e=>{
    console.log(e);//有錯誤執行這句並立刻返回錯誤信息,正確的數據不會返回
})

 

 

相同的功能,使用ES6之前的語法,不使用promise.all()要如何實現:

//不使用promise.all()

let count=0;

function fn(){
    if(count<4) return;
    console.log("數據全部接收成功");
}

function data1(){
    setTimeout(()=>{            
        console.log("data1載入成功");
        count++;
        fn();
    },2000)
}

function data2(){
    setTimeout(()=>{            
        console.log("data2載入成功");
        count++;
        fn();
    },2000)
}    

function data3(){
    setTimeout(()=>{            
        console.log("data3載入成功");
        count++;
        fn();
    },2000)
}    

function data4(){
    setTimeout(()=>{            
        console.log("data4載入成功");
        count++;
        fn();
    },2000)
}    

data1();
data2();
data3();
data4();

 

 

如果有數據接收失敗

//不使用promise.all()

let count=0;
let err=false;

function fn(){
    if(err) {
        console.log("有數據接收失敗");
        return;
    }
    if(count<4) return;
    console.log("數據全部接收成功");
}

function data1(){
    setTimeout(()=>{            
        console.log("data1載入成功");
        count++;
        fn();
    },2000)
}

function data2(){
    setTimeout(()=>{            
        console.log("data2載入失敗");
        err=true;
        fn();
    },2000)
}    

function data3(){
    setTimeout(()=>{            
        console.log("data3載入成功");
        count++;
        fn();
    },2000)
}    

function data4(){
    setTimeout(()=>{            
        console.log("data4載入成功");
        count++;
        fn();
    },2000)
}    

data1();
data2();
data3();
data4();

 

 

Promise.race()

數組中只要有一個決議為成功,則立馬決議為成功,並把值傳遞過來

//promise.race()
function data1(){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{    
            console.log("data1成功")    ;    
            resolve("data1");
        },1000)
    })
}

function data2(){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{    
            console.log("data2成功")    ;            
            resolve("data2");
        },500)
    })
}    

function data3(){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            console.log("data3成功")    ;                
            resolve("data3");
        },1000)
    })
}    

function data4(){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{    
            console.log("data4成功")    ;            
            resolve("data4");
        },1000)
    })
}    

let res=Promise.race([data1(),data2(),data3(),data4()]);
res
.then(data=>{
    console.log(data);//輸出最早成功的數據
},e=>{
    console.log(e);
})

 

 

如果有錯誤,也會立即輸出err信息

//promise.race()
function data1(){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{    
            console.log("data1成功")    ;    
            resolve("data1");
        },1000)
    })
}

function data2(){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{    
            console.log("data2失敗")    ;            
            reject("err2");
        },500)
    })
}    

function data3(){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            console.log("data3成功")    ;                
            resolve("data3");
        },1000)
    })
}    

function data4(){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{    
            console.log("data4失敗")    ;            
            resolve("err4");
        },1000)
    })
}    

let res=Promise.race([data1(),data2(),data3(),data4()]);
res
.then(data=>{
    console.log(data);//輸出最早成功的數據
},e=>{
    console.log(e);
})

 

 

如果傳入空數組,則程式被掛起

//promise.race()
function data1(){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{    
            console.log("data1成功")    ;    
            resolve("data1");
        },1000)
    })
}

function data2(){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{    
            console.log("data2失敗")    ;            
            reject("err2");
        },500)
    })
}    

function data3(){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            console.log("data3成功")    ;                
            resolve("data3");
        },1000)
    })
}    

function data4(){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{    
            console.log("data4失敗")    ;            
            resolve("err4");
        },1000)
    })
}    

let res=Promise.race([]);
res
.then(data=>{
    console.log(data);//輸出最早成功的數據
},e=>{
    console.log(e);
})

 

 

如果不使用ES6的promise.race(),實現效果如下

//不使用promise.race()
let flag=false;
function fn(data){
    if(flag) return;
    flag=true;//有請求則返回true
    console.log(data);
}

function data1(){
    setTimeout(()=>{    
        console.log("data1成功")    ;    
        fn({name:1})
    },500)
}

function data2(){
    setTimeout(()=>{    
        console.log("data2成功")    ;
        fn({name:2})    
    },600)
}    

function data3(){
    setTimeout(()=>{    
        console.log("data3成功")    ;
        fn({name:3})    
    },1000)
}    

function data4(){
    setTimeout(()=>{    
        console.log("data4成功")    ;    
        fn({name:4})
    },2000)
}    

data1();
data2();
data3();
data4();

 

 

Promise.resolve() 不管傳遞什麼值進去,都會包裝成一個promise實例

//promise.resolve()

//傳遞一個普通值
let p1=new Promise(resolve=>{
    console.log("p1決議成功");
})

let p2=Promise.resolve("p2成功");//傳遞一個普通的值,直接決議為成功

//傳遞一個promise實例
let p11=new Promise(resolve=>{
    console.log("p11決議成功");
})

let p22=Promise.resolve(p11);//傳遞一個promise實例,使得p11和p22相等
p11.then(data=>void console.log(data));
console.log(p11===p22);


//定義一個thenable對象obj
let obj={
    then(cb){
        console.log("成功")
        cb("成功啦")
    },
    oth(){
        console.log("失敗")
    }
}
//Promise.resolve(obj) 傳遞一個thenable對象
Promise.resolve(obj).then(data=>{
    console.log(data)
})

 

 

 

Promise.reject()

不管傳遞什麼值,拿到的都是傳入的值,不會進行操作和處理

//promise.reject()

//傳遞一個thenable對象obj
Promise.reject({then(){console.log("err")}})
.then(function(){
    console.log("我不會被執行");
},e=>{
    console.log(e)
})

 

 

resolve是非同步任務,會在所有同步任務完成後執行

console.log(1);

let p=new Promise(resolve=>{
    console.log(2);
    resolve();//調用resolve相等於調用.then,是非同步執行,在所有同步完成後執行
    console.log(3);
})

console.log(4);

p.then(()=>{
    console.log(5);
})

console.log(6);

 

 

把同步任務轉為非同步任務

function fn(cb){
    //返回一個決議成功的實例,並非同步執行
    return Promise.resolve(cb).then(cb=>cb());
}

fn(()=>{
    console.log("我從同步變成了非同步");
    return 1+1;
}).then(res=>{
    console.log(res);//拿到return的值
})

console.log("我是同步");

 

 

小案例

頁面中有多個板塊,需要所有圖片載入完成後再顯示

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>es6 promise</title>
</head>
<style>
    img{height:100px;}
</style>
<body>
<script>



const loadImg=(src)=>{
    return new Promise((resolve,reject)=>{
        let img=new Image();
        img.src=src;
        //圖片載入成功
        img.onload=()=>{
            resolve(img)
        }
        //圖片載入失敗
        img.onerror=(e)=>{
            reject(e)
        }
        //註意這種寫法是錯誤的,因為賦值時直接被調用,還沒有等待圖片載入已經執行完畢了
        // img.onload=resolve(img)
        // img.onerror=reject(e)
    })
}

const imgs=["1.jpg","2.jpg","3.jpg"];
// map通過遍歷把src作為參數傳入,迴圈調用loadImg,獲取到返回的image對象
Promise.all(imgs.map(src=>loadImg(src)))
.then(res=>{
    console.log(res);
    //遍歷插入DOM
    res.forEach(item=>{
        document.body.appendChild(item)
    })
})

</script>
</body>
</html>

 

 

 

失敗的情況

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>es6 promise</title>
</head>
<style>
    img{height:100px;}
</style>
<body>
<script>



const loadImg=(src)=>{
    return new Promise((resolve,reject)=>{
        let img=new Image();
        img.src=src;
        //圖片載入成功
        img.onload=()=>{
            resolve(img)
        }
        //圖片載入失敗
        img.onerror=(e)=>{
            reject(e)
        }
        //註意這種寫法是錯誤的,因為賦值時直接被調用,還沒有等待圖片載入已經執行完畢了
        // img.onload=resolve(img)
        // img.onerror=reject(e)
    })
}

const imgs=["1.jpg","22.jpg","3.jpg"
              
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 最近接手了公司兩個項目,一個PC端後臺管理系統,一個app端項目,當然使用的依然是熟悉“Vue全家桶”那套!但是,當我打開項目時,裡面的代碼是這樣的(路由模塊): 就是所有路由配置都放到一個index.js中,這多少還是讓我有點驚呆的,顯然,項目會越做越大,模塊會越加越多,那這種不分模塊的架構方式明 ...
  • ES6中class的繼承 父類(基類) 子類 extends 關鍵字 //父類 class Human{ //父類的構造函數 constructor(name,age,sex,hobby){ this.name=name this.age=age this.sex=sex this.hobby=ho ...
  • 靜態方法與靜態屬性 不會被類的實例所擁有,只有類自身擁有的屬性和方法 只能通過類來調用、 static 關鍵字(靜態方法) 類名.屬性名=屬性值(靜態屬性) //車類 class Car{ //構造函數 constructor(wheel,color,length,width){//接收參數 //給 ...
  • ,層疊樣式表,將網頁內容和顯示樣式分離,提高程式性能。 _它是一種專門描述結構文檔的表現方式的文檔,主要用於網頁風格設計,包括字體大小、顏色、以及元素的精確定位。在傳統的 網頁設計里,使得 能讓單調的 網頁更富表現力。_ 的引入方式 可以控制 文檔的顯示,但是控制文檔顯示之前,首先應在需要顯示的 文 ...
  • ,超文本標記語言,不是一種編程語言,而是一種標記語言 _思想:網頁中有很多數據,不同的數據可能需要不同的顯示效果,一個標簽相當於一個容器,想要修改容器內數據的樣式,只需要改變容器的屬性值,就可以實現容器內數據樣式的變化。_ 語言結構介紹: html學習 塊級標簽 顯示為"塊"狀,瀏覽器會在其前後顯示 ...
  • Ajax的狀態:xhr.readyState ·UNSENT 0 :創建完XHR預設就是0 ·OPENED 1 :已經完成OPEN操作 ·HEADERS_RECEIVED 2 :伺服器已經把響應頭信息返回了 ·LOADING 3 :響應主體正在返回中 ·DONE 4 :響應主體已經返回 Http的狀 ...
  • HTML結構如下: CCS結構如下: 頁面效果圖如下: 現在我們可以看到在子元素中明明設置了向右50px和向下50px,可頁面顯示的效果卻只有向右移動的沒向下移動的。 通常來說,margin是設置元素的外邊距,正常情況下設置margin值時應該是父元素相對於瀏覽器定位,子元素相對於父元素定位;而現在 ...
  • 類: 降低維護成本、使代碼高度復用、擴充方便靈活 OOP 面向對象開發 核心:封裝 類->工廠->對象 ES6中的類 //車類 class Car{ //構造函數 constructor(){ console.log("開始造車"); } } //實例化,類->對象 let c=new Car(); ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...