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)。

 

小范例:

<!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需要学习以下几点:

Promise的三种状态:

示例二,网络小爬虫

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)
})

 

posted @ 2016-08-02 16:31  张三的美丽家园  阅读(387)  评论(0编辑  收藏  举报