亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JavaScript中Promise的原理是什么及如何使用

發布時間:2023-03-23 14:07:44 來源:億速云 閱讀:214 作者:iii 欄目:開發技術

這篇文章主要介紹了JavaScript中Promise的原理是什么及如何使用的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇JavaScript中Promise的原理是什么及如何使用文章都會有所收獲,下面我們一起來看看吧。

按照我往常的理解,Promise是一個構造函數,有all、resolve、reject、then、catch等幾個方法,一般情況下,在涉及到異步操作時才會用到Promise。

所以我接下來先new一個Promise對象,并在其中進行一些異步操作:

// 使用Promise的時候一般會把它包裹在一個函數中,并在函數的最后返回這個Promise對象
function runPro()(
    var a = new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('work done!');
            resolve('success');
        }, 1000);
    });
    return a;
)
runPro()

在上面的代碼中,Promise的構造函數接收一個箭頭函數作為參數,這個箭頭函數又有兩個參數,分別是resolve和reject,我在這個箭頭函數中使用setTimeout進行了一些異步操作,異步操作中執行了resolve方法,并給resolve方法傳了一個字符串‘success’作為參數。

執行這段代碼會發現,等待了1秒鐘后(因為我在setTimeout中設置的等待時間是1000毫秒),輸出了‘work done!’。

這時候并沒有發現Promise有什么特別的作用,而且resolve和reject這兩個的作用也并沒有體現出來。

之前我們說過Promise這個構造函數上有then、catch方法,在上面的代碼片段中,runPro函數最后return了一個Promise對象,所以我們可以在runPro函數執行完成之后使用then對Promise對象進行進一步的操作:

runPro().then((res) => {
    console.log('then:', res);
    //TODO something
});

輸出結果:

JavaScript中Promise的原理是什么及如何使用

在runPro返回的Promise對象上直接調用then方法,then方法接收一個函數作為參數A,并且這個箭頭函數也會接收一個參數B,這個參數B的值就是前面代碼中resolve方法所傳遞的字符串‘success’。

執行代碼,會在1秒后首先輸出‘work done!’,緊接著輸出‘then: success’。

這個時候,就可以簡單的體現出來Promise的作用了,在前面的代碼中,then方法就像是Promise的回調函數,當Promise中的異步操作執行完之后,通過鏈式調用的方式執行回調函數。

這里的關鍵點就在于鏈式調用上,當實際使用中遇見多層回調的情況時,Promise的強大之處才能夠體現出來:

function runPro2(){
	var a = new Promise((resolve, reject) => {
		setTimeout(() => {
			resolve('success');
			console.log('this is runPro2');
		}, 1000);
	});
	return a;
};

function runPro3(){
	var a = new Promise((resolve, reject) => {
		setTimeout(() => {
			resolve('success');
			console.log('this is runPro3');
		}, 1000);
	});
	return a;
};

runPro().then(() => {
	return runPro2();
}).then(() => {
	return runPro3();
}).then(() => {
	console.log('all done')
})

到這里為止,大概已經明白了,Promise是一個在異步操作過程中,等待其中異步操作完成之后執行其回調函數的一種結構體。但是其中的原理還是模糊不清,其中resolve和reject這兩個參數還沒有搞清楚,只知道在前面的幾個代碼片段中都調用了resolve函數,resolve是做什么的并沒有體現出來。

關于resolve和reject,我以前的理解是Promise中的異步操作執行成功后調用resolve函數,異步操作執行失敗后調用reject函數,后來發現這種理解其實是不準確的。

在理解這兩個函數的正確作用之前,我們首先要知道Promise一個重要的特性:狀態

Promise的狀態:

一個Promise對象的當前狀態必須為以下三種狀態中的一種:等待(Pending)、完成(Fulfilled)、拒絕(Rejected)。

Pending:

異步操作完成之前,Promise處于等待狀態,這時候的Promise可以遷移至Fulfilled或者Rejected。

Fulfilled:

異步操作完成之后,Promise可能從Pending狀態遷移至Fulfilled狀態,Fulfilled狀態的Promise必須擁有一個不可變的終值,并且Fulfilled狀態的Promise不能遷移為其他狀態。

Rejected:

異步操作完成之后,Promise可能從Pending狀態遷移至Rejected狀態,Rejected狀態的Promise必須擁有一個不可變的拒絕原因,并且Rejected狀態的Promise不能遷移為其他狀態。

了解了Promise的三種狀態之后,我們再來說說resolve和reject這兩個函數的作用:

  • resolve函數將Promise設置為Fulfilled狀態,reject函數將Promise設置為Rejected狀態。

  • 設置為Fulfilled或者rejected狀態后,即表示Promise中的異步操作執行完成,這時程序就會執行then回調函數。

  • resolve和reject函數傳遞的參數,將由then函數中的箭頭函數接收。

實際上,理解Promise的關鍵點就在于這個狀態,通過維護狀態、傳遞狀態的方法來進行及時的回調。

所以,如下面代碼所示,當使用Promise進行異步操作的時候,其中有幾個關鍵點需要特別注意:

在一個函數中new了一個Promise對象之后,函數的最后必須把這個Promise對象return出來,否則這個函數就無法使用then函數進行回調;

異步操作中必須執行resolve或者reject函數,否則這個Promise一直處于Pending狀態,代碼就不會執行它的回調函數。

function runPro(){
	var a = new Promise((resolve, reject) => {
		setTimeout(() => {
			resolve('resolve');
			console.log('this is runPro');
		}, 1000);
	});
	return a;
}

runPro().then((res) => {
	console.log(res);
})

同樣的道理,當異步操作執行失敗時,代碼通過執行reject函數的方式,將Promise的狀態設置為Rejected,并返回一個拒絕原因:

function runPro(item){
	var a = new Promise((resolve, reject) => {
		setTimeout(() => {
			if(item >= 18) {
				console.log('item 大于 18');
				resolve('一切正常!');
			}else {
				console.log('item 小于 18');
				reject('18+電影不允許放映!');
			}
		}, 1000);
	});
	return a;
}

runPro(13)
.then((res) => {
	console.log('resolve:',res);
},(rej) => {
	console.log('reject:', rej);
})

我們給runPro函數傳遞不同的參數,runPro接受參數后進行一個異步的判斷,如果這個參數的值小于18,執行reject函數,反之則執行resolve函數,異步操作完成之后,執行then回調函數,這里的回調函數可以接收兩個箭頭函數作為參數,分別對應了resolve函數的回調和reject函數的回調,這兩個箭頭函數可以分別拿到resolve和reject傳遞的參數。

如下面截圖所示,分別給runPro傳遞兩個不同值后,得到了兩種不同的結果:

JavaScript中Promise的原理是什么及如何使用

catch函數的用法

在Promise中,catch函數可以替代reject函數使用,用來指定接收reject的回調:

function runPro(item){
	var a = new Promise((resolve, reject) => {
		setTimeout(() => {
			if(item >= 18) {
				console.log('item 大于 18');
				resolve('一切正常!');
			}else {
				console.log('item 小于 18');
				reject('18+電影不允許放映!');
			}
		}, 1000);
	});
	return a;
}

runPro(13)
.then((res) => {
	console.log('resolve:',res);
})
.catch((rej) => {
	console.log('catch:', rej);
})

如上面代碼所示,對調函數then只有一個箭頭函數作為參數,這種情況下,這個箭頭函數就被指定用來接收resolve函數的回調,而reject函數的回調則被catch函數來接收:

JavaScript中Promise的原理是什么及如何使用

這個地方使用catch函數來接收reject的回調有一個優點,當前面的then回調函數中出現位置錯誤時,catch函數可以對錯誤信息進行處理,而不會導致代碼報錯。這個原理和常用的try/catch語句相同。

function runPro(item){
    var a = new Promise((resolve, reject) => {
        setTimeout(() => {
            if(item >= 18) {
                console.log('item 大于 18');
                resolve('一切正常!');
            }else {
                console.log('item 小于 18');
                reject('18+電影不允許放映!');
            }
        }, 1000);
    });
    return a;
}
runPro(19)
.then((res) => {
    console.log(adc); // 這里的adc是一個未定義的變量,當代碼執行到這里時,會拋出Error信息導致代碼卡死
    console.log('resolve:',res);
}, (rej) => {
    console.log('reject:',rej);
});
runPro(19)
.then((res) => {
    console.log(abc); // 這里的abc是一個未定義的變量,但是由于后邊使用.catch函數進行了異常捕獲,所以程序不會報錯。而且錯誤原因也會作為參數傳遞到后面.catch函數的參數中
    console.log('resolve:',res);
})
.catch((rej) => {
    console.log('catch:', rej);
})

JavaScript中Promise的原理是什么及如何使用

all函數 / race函數并行異步操作

Promise的all函數和race函數都提供了并行異步操作的能力,二者的區別在于,當這些并行的異步操作耗時不同時,all函數是在所有的異步操作都執行完之后才會執行,而race函數則會在第一個異步操作完成之后立即執行。

function runPro1(){
	var a = new Promise((resolve, reject) => {
		setTimeout(() => {
			resolve('success');
			console.log('this is runPro1');
		}, 1000);
	});
	return a;
}
function runPro2(){
	var a = new Promise((resolve, reject) => {
		setTimeout(() => {
			resolve('success');
			console.log('this is runPro2');
		}, 2000);
	});
	return a;
};

function runPro3(){
	var a = new Promise((resolve, reject) => {
		setTimeout(() => {
			resolve('success');
			console.log('this is runPro3');
		}, 3000);
	});
	return a;
};

Promise.all([runPro1(), runPro2(), runPro3()])
.then((res) => {
	console.log('all:', res);
})

JavaScript中Promise的原理是什么及如何使用

function runPro1(){
	var a = new Promise((resolve, reject) => {
		setTimeout(() => {
			resolve('success');
			console.log('this is runPro1');
		}, 1000);
	});
	return a;
}
function runPro2(){
	var a = new Promise((resolve, reject) => {
		setTimeout(() => {
			resolve('success');
			console.log('this is runPro2');
		}, 2000);
	});
	return a;
};

function runPro3(){
	var a = new Promise((resolve, reject) => {
		setTimeout(() => {
			resolve('success');
			console.log('this is runPro3');
		}, 3000);
	});
	return a;
};

Promise.races([runPro1(), runPro2(), runPro3()])
.then((res) => {
	console.log('all:', res);
})

JavaScript中Promise的原理是什么及如何使用

如上兩個代碼片段所示,all函數和race都接收一個數組作為參數,這個數組中的值就是我們要進行并行執行的異步操作。這里我們同樣使用then函數作為異步操作完成的回調函數。同時我們通過console輸出發現,在race函數的回調函數開始執行的時候,另外兩個沒有執行完成的異步操作并沒有停止,依舊在執行。

關于“JavaScript中Promise的原理是什么及如何使用”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“JavaScript中Promise的原理是什么及如何使用”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

昆山市| 兴义市| 东乌| 通辽市| 永康市| 响水县| 阳高县| 晋城| 桑日县| 九龙县| 青田县| SHOW| 舞阳县| 天镇县| 广安市| 根河市| 台江县| 油尖旺区| 民权县| 广南县| 泽州县| 福安市| 登封市| 咸阳市| 双江| 乌兰浩特市| 托里县| 锦州市| 承德市| 迁西县| 卓尼县| 安顺市| 海丰县| 德州市| 凌海市| 柏乡县| 什邡市| 垦利县| 南京市| 绥江县| 阳新县|