Promise簡(jiǎn)介
Promise是一種解決異步回調(diào)問(wèn)題而發(fā)展的編程語(yǔ)言特性,在各種語(yǔ)法中都有支持,比如在JavaScript(ECMAScript 6)/Java(8)/Node.js(0.12)都有原生的支持,而沒(méi)有原生支持的語(yǔ)言更可以通過(guò)第三方框架來(lái)簡(jiǎn)單引入(比如大名鼎鼎的Q)
為什么說(shuō)異步回調(diào)不是好的解決方案
1.Callback Hell
loadScript("a.js",function(){
loadScript("b.js",function(){
loadScript("c.js",function(){
loadScript("d.js",function(){
loadScript("e.js",function(){
console.log("Fuck to load async files")
}
})
})
})
})
2.依賴習(xí)慣編碼
function asyncFunc(callback){
doSomething(function(err, result){
if(err){
callback(err, null);
}
callback(null, result);
})
}
asyncFunc(function(err,result){
if(err){
console.error(err);
}
console.log(result);
})
anotherAsyncFunc(function(result,err){
if(result){
console.log("Fuck why the first is result");
}
})
還有種種,比如控制流難以書寫(多個(gè)不同異步任務(wù)的條件判斷和進(jìn)度控制),try/catch無(wú)法捕獲回調(diào)異常…………種種原因逼迫人們選擇更好的解決方案
Promise的核心
此處以Node.js(v0.12)為例,部分術(shù)語(yǔ)可能不同編程語(yǔ)言實(shí)現(xiàn)時(shí)不同,在JavaScript中,Promise是一個(gè)內(nèi)置對(duì)象
友情提示:以下東西僅為裝逼,可跳過(guò)
三種狀態(tài):
fullfied:被resolve后的狀態(tài)
rejected:被reject后的狀態(tài)
pending:初始狀態(tài)兩個(gè)調(diào)用:
then(onFulfilled, onRejected):在被resolve后執(zhí)行onFulfilled函數(shù),而被rejected后執(zhí)行onRejected函數(shù)。并且實(shí)際上每次調(diào)用Promise的then都會(huì)返回一個(gè)新的Promise對(duì)象
catch(onRejected):then(undefined, onRejected)的語(yǔ)法糖,被rejected后執(zhí)行onRejected函數(shù)-
狀態(tài)轉(zhuǎn)變:
resolve(value):語(yǔ)法糖,返回一個(gè)立即被fullfied且轉(zhuǎn)變?yōu)?code>fullfied狀態(tài)的Promise對(duì)象,等價(jià)于:new Promise(function(resolve){ resolve(value); });
reject(value):語(yǔ)法糖,返回一個(gè)立即被resolve且轉(zhuǎn)變?yōu)?code>rejected的Promise對(duì)象,等價(jià)于:
```javascript
new Promise(function(resolve){
resolve(value);
});
```
- 控制流:
Promise.all([promise1, promise2, ...]):當(dāng)全部Promise對(duì)象被resolve時(shí)調(diào)用then(onFulfilled(value))(value為數(shù)組的值);或者任何一個(gè)Promise對(duì)象被reject時(shí)調(diào)用catch(onRejected)
Promise.race([promise1, promise2, ...]):當(dāng)任何Promise對(duì)象被resolve或者reject時(shí)調(diào)用then(onFulfilled(value))或者catch(onRejected)
Promise的簡(jiǎn)單用法
1.Easy Mode
function asyncFunction() {
if (1 === 1){
return Promise.resolve("OK");
}
else{
return Promise.reject(new Error("Wrong"));
}
}
asyncFunction().then(function(val){
console.log(val);
}).catch(function(err){
console.error(err);
})
OK
2.Normal Mode
asyncFunction().then(function(val){
console.log(val);
return "First";
}).then(function(val){
console.log(val);
return "Second";
}).then(function(val){
throw new Error("Fuck");
console.log(val);
}).catch(function(err){
console.error(err);
})
console.log("Start!");
Start
OK
First
[Error: Fuck]
3.Hard Mode
function anotherAsyncFunction(){
if (2 != 2){
return Promise.resolve("OK");
}
else{
return Promise.reject(new Error("Wrong"));
}
}
Promise.all([asyncFunction(),anotherAsyncFunction()]).then(function(val){
console.log("All:" + val);
}).catch(function(err){
console.error("All:" + err);
});
Promise.race([asyncFunction(),anotherAsyncFunction()]).then(function(val){
console.log("Race:" + val);
}).catch(function(err){
console.error("Race:" + err);
});
Race:OK
All:Error: Wrong
后話
擁抱Promise,告別Callback,你我值得擁有。連古老的OO圣教——Java大法都擁抱Lambda和Promise,你還在等什么?
public F.Promise<JsonNode> post(String formData){
WSRequest request = client.url(url);
F.Promise<WSResponse> responsePromise = request
.setContentType("application/x-www-form-urlencoded")
.post(formData);
F.Promise<JsonNode> jsonNodePromise = responsePromise.map(value -> {
return value.asJson();
});
responsePromise.onFailure(error -> {
Logger.error(error);
});
return jsonNodePromise;
}