10慕課網《進擊Node.js基礎(一)》初識promise

首先用最簡單的方式實現一個動畫效果javascript

<!doctype>
<html>
<head>
<title>Promise animation</title>
<style type="text/css">
    .ball {
        width: 40px;
        height: 40px;
        border-radius: 20px;
    }

    .ball1 {
        background: red;
    }
    .ball2 {
        background: yellow;
    }
    .ball3 {
        background: green;
    }

</style>
</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, cd){
            //每13毫秒改變一次圓球的位置,直到到達指定位置
            setTimeout(function(){
                var marginLeft = parseInt(ball.style.marginLeft,10)
                //球達到預期位置
                if(marginLeft === distance){
                    cd && cd()
                }else{
                    //球在左側
                    if(marginLeft < distance){
                        marginLeft++
                    }else{
                        //球在右側
                        marginLeft--
                    }
                    //調整球的位置
                    ball.style.marginLeft = marginLeft
                    animate(ball, distance, cd)
                }
            },13)
        }
        //控制動畫
        animate(ball1, 100,function(){
            animate(ball2, 200, function(){
                animate(ball3, 150, function(){
                    animate(ball2, 150, function(){
                        animate(ball1, 150, function(){

                        })
                    })
                })
            })
        })

    </script>
</body>
</html>

 使用promise實現相同功能css

<!doctype>
<html>
<head>
<title>Promise animation</title>
<style type="text/css">
    .ball {
        width: 40px;
        height: 40px;
        border-radius: 20px;
    }

    .ball1 {
        background: red;
    }
    .ball2 {
        background: yellow;
    }
    .ball3 {
        background: green;
    }
</style>

<script src="./node_modules/bluebird/js/browser/bluebird.js" type="text/javascript"></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')



        var Promise = window.Promise

        function promiseAnimate(ball, distance){
            return new Promise(function(resolve, reject){
                //球,移動距離,回調函數
                function _animate(){
                    //每13毫秒改變一次圓球的位置,直到到達指定位置
                    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, 150)
            })
            .then(function(){
                return promiseAnimate(ball2, 150)
            })
            .then(function(){
                return promiseAnimate(ball1, 150)
            })
    </script>
</body>
</html>

 

promise對象三種狀態:

  • -未完成(pending)
  • -已完成(fulfiled)
  • -失敗(rejected)

 promiseA與promiseA+不一樣點:

  • -A+規範經過屬於thenable來區分promise對象
  • -A+定義onFulfilled/onRejected必須是做爲函數來調用,並且調用過程必須是異步的
  • -A+嚴格定義了then方法鏈式調用時onFulfilled/onRejected的調用順序

 promise then 方法

將異步執行的回調函數放入then方法中,規範鏈式書寫html

promiseObj.then(onFunction, onRejected)

onFulfilled = function(value){
  return promiseObj2        
}

onRejected = function(err){}

 

 promise庫有不少

  • bluebird
  • Q
  • then.js
  • es6-promise
  • ypromise
  • async
  • native-promise-only

 使用promise重寫爬蟲

對比:07慕課網《進擊Node.js基礎(一)》HTTP小爬蟲java

 

var http = require('http')
var Promise = require('bluebird')
var cheerio =  require('cheerio') //使用模塊
var baseUrl = 'http://www.imooc.com/learn/'
var videoIds = [728,637,348]


function filterChapters(html){
    //能夠像jQuery同樣使用
    var $ = cheerio.load(html)

    var chapters = $('.chapter')
    var title = $('.clearfix h2').text()
    var number = $('.js-learn-num').text()

    // courseData = {
    //         title : title,
    //         number : 0,
    //         videos : [{
    //             chapterTitle:'',
    //             videos:[{
    //             title:'',
    //             id:''
    //         }]
    //     }

    var courseData = {
        title : title,
        number : number,
        videos : []
    }

    chapters.each(function(item){
        var chapter = $(this)
        var chapterTitle = chapter.find('h3').text()
        var videos = chapter.find('.video').children('li')
        var chapterData = {
            chapterTitle :chapterTitle.trim(),
            videos:[]
        } 

        videos.each(function(item){
            var video = $(this).find('a')
            var videoTile = video.text()
            var id = video.attr('href').split('video/')[1]
            chapterData.videos.push({
                title: videoTile.trim(),
                id : id
            })
        })
        courseData.videos.push(chapterData)

    })
    return courseData
}

function printCourseInfo(coursesData){

    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

            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(){
                resolve(html)

                //var courseData = filterChapters(html)
                //printCourseInfo(courseData)
            })
        }).on('errer',function(e){
            reject(e)
            //console.log('出錯')
        })


    })
}

var fetchCourseArray = []
videoIds.forEach(function(id){
    fetchCourseArray.push(getPageAsync(baseUrl + id)) 
})

Promise
    .all(fetchCourseArray)
    .then(function(pages){
        //對多個數據處理
        var coursesData = []

        pages.forEach(function(html){
            var curses = filterChapters(html)
            coursesData.push(curses)
        })

        coursesData.sort(function(a,b){
            return a.number < b.number
        })

        printCourseInfo(coursesData)
    })

 

 

HTTP和HTTPS

HTTPS在http的基礎上進行了加密node

運行HTTPS服務,.pem文件還須要另外的方式建立es6

var https = require('https')
var fs = require('fs')

var options = {
    key: fs.readFileSync('ssh_key.pem'),//ssl 文件
    key: fs.readFileSync('ssh_cert.pem'),//證書文件

}

//運行HTTPS服務器
https.createServer(options, function(req,res){
    res.writeHead(200)
    res.end('hello world'+ req)
}).listen(8090)
相關文章
相關標籤/搜索