1. 程式人生 > >Promise的總結

Promise的總結

Promise作為Nodejs的曾經的黑科技,一直優待著銳意寫出漂亮程式碼的人們。簡而言之,其解決了一個回撥陷阱的問題,Nodejs作為以回撥為品牌的語言平臺,其一直得益於其瘋狂的回撥模式,網上更有各種評測,其以單執行緒支撐萬計的訪問量,頗有點喬峰在聚賢莊的意思。

假設這麼一個場景:我們需要讀取檔案中的資料,然後提取其中我們需要的資訊,傳送到後臺程式中,並接收其結果。程式碼示意如下:

fs.readFile('aaa.txt', function(content, e){
	if(e){
		console.info("開啟檔案失敗");
		return;
	}
	let name = content.substring(3,55);
	sendToOther(name, function(e){
		if(e){
			console.info("you lost!");
		}else {
			console.info("你成功啦");
		}
	});
});

其實上面的程式碼看著還行,但是如果我在你成功之後,需要將寫日誌,日誌書寫失敗,需要發簡訊,簡訊傳送成功與否,需要記錄,以備未來計費。。。

如果一直回撥下去,我估計已經沒有人能回得來神了。試想,我們在看原始碼的時候,經常頭疼的就是呼叫棧,看到裡面,想不起外面的上下文是什麼情況,又從debugger裡點出來,看外面一層的方法呼叫的上下文,以及其想幹個啥。

 

那麼Promise就是為了解決此問題,而出現的。上程式碼:

首先要明白,鏈式呼叫,現在許多程式,尤其是一些cs的程式都喜歡這個調調,其核心就是被設定或處理的主體即this,會在處理完成後返回。

那麼上面的程式,我們如何進行Promise呢。

new Promise(function(resolve, reject){
	fs.readFile('aaa.txt', function(content){
		if(e){
			reject("開啟檔案失敗");
			return ;
		}
		resolve(content);
        // 以下程式會立即執行,不會等待resolve返回的
        console.info("I will be printed right now!!!!!")
	}).then(function(content){
		let name = content.substring(3,55);
		return name;
	}).then(function(name){ // ******1******
		return new Promise(function(resolve, reject)){
			sendToOther(name, function(e){
				if(e){
					console.info("you lost!");
					reject("lost when sendToOther");
				}else {
					console.info("你成功啦");
					resolve("ok");
				} 
			});
		}		
	}).then(function(ok)){
		//ok is ok 
		// go to send sms
	}catch(function(e){
		console.error(e);
	});
});

由上述程式碼,可以知道,其實首個方法,用new Promise來解決,其裡面的回撥裡,可以用then來解決同步的呼叫,如果想用 then來解決非同步的回撥,這時候,要動用then裡返回Promise的方法來重新開始。

所以有兩個地方要明確:

1、then方法時要兩個引數,當然後者經常省略。用typescript的限制寫法,可以如下:

    fufilled:(a:any)=>any

    failed:(a:any)=>any

    ps:then中的函式,只能來傳傳遞一個引數,不能是多個

    那麼,以下的方法都可以認為是第一個引數有值,第二個沒值

    如果想重新連起來,就弄個函式,接收上面的引數,並且返回一個Promise

2、如果想處理then中的回撥,需要用新的Promise來返回

3、注意程式執行順序,跟在resolve和reject後的內容會立即執行,不是等你的resolve返回後才執行。所以可以理解,Promise僅來協調resolve和then中指定的程式碼執行順序。