Promise是抽象異步處理對象以及對其進行各類操做的組件。Promise並非從JavaScript中發祥的概念。Promise最初被提出是在 E語言中, 它是基於並列/並行處理設計的一種編程語言。如今JavaScript也擁有了這種特性,這就是本文所介紹的JavaScript Promise。另外,若是說到基於JavaScript的異步處理,我想大多數都會想到利用回調函數。 Promise是一個類,能夠建立實例表明承諾,而何時會用到承諾 ,通常是異步任務,就是須要很長時間執行的時間html
用new Promise 實例化的promise對象有如下三個狀態。git
promise對象的狀態,從Pending轉換爲Fulfilled或Rejected以後, 這個promise對象的狀態就不會再發生任何變化。也就是說,Promise與Event等不一樣,在.then 後執行的函數能夠確定地說只會被調用一次。另外,Fulfilled和Rejected這兩個中的任一狀態均可以表示爲Settled(不變的)。github
通常狀況下咱們都會使用 new Promise()
來建立promise對象,可是除此以外咱們也可使用其餘方法。 在這裏,咱們將會學習如何使用 Promise.resolve
和 Promise.reject
這兩個方法。編程
let Promise = require('./Promise');
let p1 = new Promise(function(resolve,reject){
setTimeout(function(){
let num = Math.random();//生成一個隨機數
console.log(num);
if(num>.5){
resolve('大成功');
}else{
reject('小失敗');
}
},2000);
});
p1.then(function(value){
console.log('成功1=',value);
},function(reason){
console.log('失敗1=',reason);
});
p1.then(function(value){
console.log('成功2=',value);
},function(reason){
console.log('失敗2=',reason);
});
複製代碼
.then
方法。function getURL(URL) {
return new Promise(function (resolve, reject) {
var req = new XMLHttpRequest();
req.open('GET', URL, true);
req.onload = function () {
if (req.status === 200) {
resolve(req.responseText);
} else {
reject(new Error(req.statusText));
}
};
req.onerror = function () {
reject(new Error(req.statusText));
};
req.send();
});
}
var request = {
comment: function getComment() {
return getURL('http://azu.github.io/promises-book/json/comment.json').then(JSON.parse);
},
people: function getPeople() {
return getURL('http://azu.github.io/promises-book/json/people.json').then(JSON.parse);
}
};
function main() {
return Promise.all([request.comment(), request.people()]);
}
// 運行示例
main().then(function (value) {
console.log(value);
}).catch(function(error){
console.log(error);
});
複製代碼
Promise.all
在接收到的全部的對象promise
都變爲 FulFilled
或者 Rejected
狀態以後纔會繼續進行後面的處理, 與之相對的是 Promise.race
只要有一個promise
對象進入 FulFilled
或者 Rejected
狀態的話,就會繼續進行後面的處理。// `delay`毫秒後執行resolve
function timerPromisefy(delay) {
return new Promise(function (resolve) {
setTimeout(function () {
resolve(delay);
}, delay);
});
}
// 任何一個promise變爲resolve或reject 的話程序就中止運行
Promise.race([
timerPromisefy(1),
timerPromisefy(32),
timerPromisefy(64),
timerPromisefy(128)
]).then(function (value) {
console.log(value); // => 1
});
複製代碼
介紹一些第三方實現的和Promise兼容的類庫json
Q
實現了 Promises 和 Deferreds 等規範。 它自2009年開始開發,還提供了面向Node.js的文件IO API Q-IO 等, 是一個在不少場景下都能用獲得的類庫,在angular.js裏的promise就是用的q。//let Q = require('q');
let Q = {
defer(){
let success,error;
return {
resolve(data){
success(data);
},
reject(err){
error(err);
},
promise:{
then(onFulfilled,onRejected){
success = onFulfilled;
error = onRejected;
}
}
}
}
}
let fs = require('fs');
function readFile(filename){
let defer = Q.defer();
fs.readFile(filename,'utf8',function(err,data){
if(err)
defer.reject(err);
else{
defer.resolve(data);
}
});
return defer.promise;
}
readFile('1.txt').then(function(data){
console.log(data);
});
複製代碼
/**
* bluebird是世界最快的promise庫
* //它能把任意的經過回調函數實現的異步API換成promiseapi
*/
let Promise = require('bluebird');
let fs = require('fs');
function promisifyAll(obj) {
for (let key in obj) {
if (obj.hasOwnProperty(key) && typeof obj[key] == 'function') {
obj[key+'Async'] = Promise.promisify(obj[key]);
}
}
}
//它會遍歷對象上面的全部方法,而後對每一個方法添加一個新的方法 Async
promisifyAll(fs);
fs.readFileAsync('./1.txt', 'utf8').then(data => console.log(data));
複製代碼
Q 和 Bluebird 這兩個類庫除了都能在瀏覽器裏運行以外,充實的API reference也是其特徵。api