2015年發佈了ES6標準,所謂 Promise,就是ES6標準的一個對象,用來傳遞異步操做的消息。它表明了某個將來纔會知道結果的事件(一般是一個異步操做),而且這個事件提供統一的 API,可供進一步處理。
有了 Promise 對象,就能夠將異步操做以同步操做的流程表達出來,避免了層層嵌套的回調函數。此外,Promise 對象提供統一的接口,使得控制異步操做更加容易。
var promise = new Promise(function(resolve, reject) {
if (/* 異步操做成功 */){
resolve(value);
} else {
reject(error);
}
});
promise.then(function(value) {
// success
}, function(value) {
// failure
});
Promise函數接受一個函數做爲參數,該函數的兩個參數分別是 resolve 方法和 reject 方法。
若是異步操做成功,則用 resolve 方法將 Promise 對象的狀態,從「未完成」變爲「成功」(即從 pending 變爲 resolved);
若是異步操做失敗,則用 reject 方法將 Promise 對象的狀態,從「未完成」變爲「失敗」(即從 pending 變爲 rejected)。javascript
小范例:css
<!DOCTYPE> <html lang="en"> <head> <meta charset="UTF-8"> <title>promise animation</title> <style type="text/css"> .ball{ width: 40px; height:40px; border-radius: 20px; } .ball1{ background-color: red; } .ball2{ background-color: yellow; } .ball3{ background-color: green; } </style> <script src="node_modules/bluebird/js/browser/bluebird.js"></script> </head> <body> <div class="ball ball1" style="margin-left:0;"></div> <div class="ball ball2" style="margin-left:0;"></div> <div class="ball ball3" style="margin-left:0;"></div> <script type="text/javascript"> var ball1=document.querySelector('.ball1'); var ball2=document.querySelector('.ball2'); var ball3=document.querySelector('.ball3'); function animate(ball,distance,cb){ setTimeout(function(){ var marginLeft=parseInt(ball.style.marginLeft,10); if(marginLeft===distance){ cb&&cb(); }else{ if(marginLeft<distance){marginLeft++;} else{marginLeft--;} ball.style.marginLeft=marginLeft; animate(ball,distance,cb); //不斷重複作這件事知道球移動到咱們指望的位置 } },13) } // animate(ball1,100,function(){ // animate(ball2,200,function(){ // animate(ball3,300,function(){ // animate(ball3,150,function(){ // animate(ball2,150,function(){ // animate(ball1,150,function(){ // }) // }) // }) // }) // }) // }) var Promise=window.Promise; function promiseAnimate(ball,distance){ return new Promise(function(resolve,reject){ function _animate(){ setTimeout(function(){ var marginLeft=parseInt(ball.style.marginLeft,10) if(marginLeft===distance){ resolve() }else{ if(marginLeft<distance){ marginLeft++ }else{ marginLeft-- } ball.style.marginLeft=marginLeft+'px' _animate() } },13) } _animate() }) } promiseAnimate(ball1,100) .then(function(){ return promiseAnimate(ball2,200) }) .then(function(){ return promiseAnimate(ball3,300) }) .then(function(){ return promiseAnimate(ball3,150) }) .then(function(){ return promiseAnimate(ball2,150) }) .then(function(){ return promiseAnimate(ball1,150) }) </script> </body> </html>
關於Promise須要學習如下幾點:html
Promise的三種狀態:java
示例二,網絡小爬蟲node
var http=require('http') var cheerio=require('cheerio') var baseUrl='http://www.imooc.com/learn/' var videoIds=[348,259,197,134,75] //var url='http://119.29.109.156:8080/ServerTest01/' //each 和 forEach區別在於each能夠改變數組中的數據 function filterChapters(html){ var $=cheerio.load(html) var chapters=$('.chapter') var title=$('.hd .l').text() var number=parseInt($($('.meta-value strong')[3]).text().trim(),10) /*courseData={ title:title, number:number, videos: [{ chapterTitle:'' videos:[ title:'' id:'' ] }] }*/ var courseData={ videos:[], number:number, title:title } //將課程名和學習人數進行寫入 courseData.title=title courseData.number=number chapters.each(function(item){ var chapter=$(this) var chapterTitle=chapter.find('strong').text() var videos=chapter.find('.video').children('li') var chapterData={ chapterTitle:chapterTitle, videos:[] } videos.each(function(item){ var video=$(this).find('.studyvideo') var videoTitle=video.text() var videoid=video.attr('href').split('video/')[1] chapterData.videos.push({ title:videoTitle, id:videoid }) }) courseData.videos.push(chapterData) }) return courseData } function printCourseInfo (coursesData) { console.log('printCourseInfo') coursesData.forEach(function(courseData){ console.log(courseData.number+' 人學過 '+courseData.title+'\n') }) coursesData.forEach(function(courseData){ console.log('### '+courseData.title+'\n') courseData.videos.forEach(function(item){ var chapterTitle=item.chapterTitle console.log(chapterTitle+'\n') item.videos.forEach(function(video){ console.log(' ['+video.id+'] '+video.title+'\n') }) }) }) } function getPageAsync(url){ return new Promise(function(resolve,reject){ console.log('正在爬取 '+url) http.get(url,function(res){ var html='' res.on('data',function(data){ html += data }) res.on('end',function(){ console.log('爬取 '+ url+' 成功') resolve(html) }) }).on('error',function(e){ reject(e) console.log('獲取課程數據出錯') }) }) } //存放全部課程的html的一個數組 var fentchCourseArray=[] videoIds.forEach(function(id){ fentchCourseArray.push(getPageAsync(baseUrl+id)) }) Promise .all(fentchCourseArray) .then(function(pages){ var coursesData=[] pages.forEach(function(html){ console.log("1111") var courses=filterChapters(html) coursesData.push(courses) }) coursesData.sort(function(a,b){ return a.number<b.number }) printCourseInfo(coursesData) })