• 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+'
    ') 
        }) 
        coursesData.forEach(function(courseData){ 
            console.log('### '+courseData.title+'
    ') 
            courseData.videos.forEach(function(item){ 
                var chapterTitle=item.chapterTitle 
                console.log(chapterTitle+'
    ') 
                item.videos.forEach(function(video){ 
                    console.log(' ['+video.id+'] '+video.title+'
    ') 
                }) 
            }) 
        }) 
    } 
    
    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)
    })
  • 相关阅读:
    android事件拦截处理机制详解
    序列化
    事件系统的一般性
    Android应用启动、退出分析
    Android Activity.startActivity流程简介
    ActivityThread
    Android Activity学习笔记——Activity的启动和创建
    attachBaseContext
    新认识的类
    深入理解Intent和IntentFiler(一)
  • 原文地址:https://www.cnblogs.com/greatluoluo/p/5729798.html
Copyright © 2020-2023  润新知