Node.js之Promise

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)
})
相關文章
相關標籤/搜索