8.NodeJs之小白初识promise

作者: coderLfy | 来源:发表于2017-01-16 16:37 被阅读199次

Promise入门级介绍


本文是观看了慕课网上的进击的NodeJs(二)后写的小结,感谢Scott老师

1. Promise到底是什么?

2. 为什么要用promise

  • 因为是ES6规范中的一个重要对象,学习没有坏处!
  • promise是为了处理回调地狱的新的处理
  • 让代码简洁,增加可读性的一种方式

3. promise 的属性和方法

首先介绍一下promise有几种状态:

new Promise(/ * executor * / function(resolve,reject){...});

  • pedding: 一开始创建promise时的状态,不属于成功与失败
  • Resolved(成功状态)
  • rejected(失败)

这些状态只能从pedding到成功,或者pending到失败,不可逆,不可停止;

4. promise 的属性与方法

属性:

Promise.length
Length属性,其值始终为1(构造函数参数的数目)

Promise.prototype
表示 Promise 构造器的原型.

方法:

  1. Promise.all(iterable)
    返回一个Promise,当可迭代参数中的所有promise都满足或拒绝时,只要可迭代参数中的一个promise拒绝就满足。如果返回的promise满足,则使用来自履行的promise中的值的数组来实现,其具有与可迭代中定义的顺序相同的顺序。如果返回的promise拒绝,它被拒绝的原因来自可迭代的第一个promise拒绝。此方法可用于聚合多个promise的结果。
  1. Promise.race(iterable)
    返回一个promise,只要promise中的一个promise满足或拒绝,就满足或拒绝该promise,以及该promise中的值或原因。
  1. Promise.reject(reason)
    返回一个Promise被拒绝,并给出的理由对象。
  1. Promise.resolve(value)
    返回Promise一个与给定值解析的对象。如果该值是一个thenable(即有一个then方法),返回的承诺将“跟随 ”是thenable,采用其最终状态; 否则返回的promise将使用该值来完成。一般来说,如果你不知道一个值是一个承诺或没有,Promise.resolve(value)它反而和返回值作为一个承诺工作。

5. 怎么用promise

先从一个例子来了解一下回调地狱的感觉= =

这个例子是三个小球的移动的例子,以注释的方式来解释例子

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>promise animation</title>
  <--这里是引入bluebird,我注释掉后一样可以使用Promise,因为现在的浏览器本身可以识别Promise 在node中要require('promise')-->
  <!-- <script src="./node_modules/bluebird/js/browser/bluebird.js" charset="utf-8"></script> -->
  <style media="screen">
    .ball{
      width: 40px;
      height: 40px;
      border-radius: 50%;
    }
    .ball1{
      background: red;
    }
    .ball2{
      background: blue;
    }
    .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, cb){
  //   setTimeout(function(){
  //     var marginLeft = parseInt(ball.style.marginLeft,10);
  //     if(marginLeft === distance){
  //       cb && cb() //这里是短路表达式,cb存在?执行cb()
  //     }else{
  //       if (marginLeft < distance){
  //           marginLeft++;
  //       }else{
  //         marginLeft--;
  //       }
  //       ball.style.marginLeft = marginLeft +'px';
  //       animate(ball, distance, cb);
  //     }
  //   },13)
  // }

//callback回调函数的嵌套
  // animate(ball1, 100, function(){
  //   animate(ball2, 200, function(){
  //     animate(ball3, 300, function(){
  //       animate(ball3, 150, function(){
  //         animate(ball2, 150,function(){
  //           animate(ball1, 150, function(){
  //
  //           });
  //         });
  //       });
  //     });
  //   });
  // });




/* 这是以Promise的形式 */
var Promise = window.Promise;
function promiseAnimate(ball, distance){
    //把promise对象返回
  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()

  })
}
//then有点类似类似链式调用,这种方式看着简洁,代码可读性高
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>

6. promise库(Scott老师推荐bluebird)

  • 以下promise库大同小异,学习期间重点是学习promise用法,各个差异自行百度,最新的浏览器都支持了promise,学习的时候也可以不用引库
  • bluebird
  • Q
  • then.js
  • es6-promise
  • ypromise
  • async
  • native-promise-only
  • .....

7.PromiseA与A+不同点

  • A+ 规范通过术语thenable来区分promise对象
  • A+ 定义了onFulfilled/onRejected必须是作为函数来调用的,而且调用过程必须是异步
  • A+ 严格定义了then 方法链式调用时onFulfilled/onRejected的调用顺序

8.Promise then方法

promise会保证回调的顺序,链式调用then方法参数里的回调函数会依次调用,这then方法不会立即执行,只有前面的promise成功后才会进行

promiseObj.then(onFulfilled,onRejjected){
    onFunlilled = function(value){
        return promiseObj2
    }
    inRejected = function(err){
        
    }
}

9. 简单HTTPS服务器的搭建

http与https

HTTPS是在HTTP的多了一层SSL/TLS,多了一次握手从三次握手改成了四次握手,这里就不多聊,有兴趣可以多多百度,主要是为了学习怎么搭建一个HTTPS的本地服务器

var https = require('https');
var fs = require('fs');//注入读取文件

//key与cert
var options = {
  key:fs.readFileSync('ssh_key.pem'),
  cert:fs.readFileSync('ssh_cert.pem')
};

https
  .createServer(options,function(req, res){
    res.writeHead(200);
    res.end('hello');
  })
  .listen(8080);

10. 用promise优化爬虫

在最新的版本里已经有了Promise这个函数了,老板本是没有这个函数的!要加第三方!

var http = require('http');
var cheerio = require('cheerio');//引入cheerio
//新版本内置Promise了
var baseUrl = 'http://www.imooc.com/learn/';
// var url = 'http://www.imooc.com/learn/348';
var videoIds = [348, 259, 197, 134, 75];
function filterChapters(html){
  var $ = cheerio.load(html);//变成jq模样便于理解
  var chapters = $('.chapter');
  var title = $('#main .path span').text();
  //由于该爬虫只能爬到源代码上的数据,而人数又是ajax获取的,所以人数拿不到
// courseData = {
// title:title,
//  videos:[{
//     chapterTitle:'',
//     videos:[{
//       title:'',
//       id:''
//     }]
//   }]
// }
  var courseData = {
    title:title,
    videos:[]
  };
  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(){
      var video = $(this).find('.J-media-item');
      var videoTitle = video.text();
      var id = video.attr('href').split('video/')[1];
      chapterData.videos.push({
        title:videoTitle,
        id:id
      });
    });
    courseData.videos.push(chapterData);
  });
  return courseData;
}
function printCourseInfo(coursesData){
  coursesData.forEach(function(courseData){
    console.log('### ' + courseData.title + '\n');
    courseData.videos.forEach(function(item){
      var chapterTitle = item.chapterTitle;
      // console.log(chapterTitle + '\n');
      console.log(chapterTitle.replace(/\s+/g,"")+"\n");
      item.videos.forEach(function(video){
        // console.log('【' + video.id +'】' + video.title + '\n');
        console.log("【"+ video.id.replace(/\s+/g,"") +"】"+video.title.replace(/\s+/g,"") +"\n");
      });
    });
  });
}
function getPageAsync(url){
  return new Promise(function(resolve, reject){//返回一个Promise对象
      console.log('正在爬取 '+ url);
      http.get(url,function(res){
        var html = '';
        res.on('data',function(data){//data事件
          html += data;
        });
        res.on('end',function(){//end 事件
          resolve(html);//成功获取
        });
      }).on('error',function(e){//error
        reject(e);//失败
        console.log('获取课程数据失败!');
      });
  });
}
var fetchCourseArray = [];//存放Promise对象的数组
videoIds.forEach(function(id){
  fetchCourseArray.push(getPageAsync(baseUrl + id));
});
Promise
  .all(fetchCourseArray)//等待所有的异步爬取结束以后利用then方法进行下一步
  .then(function(pages){
    var coursesData = [];
    pages.forEach(function(html){
      var courses = filterChapters(html);
        coursesData.push(courses);
    });
    printCourseInfo(coursesData);
  });

相关文章

  • 8.NodeJs之小白初识promise

    Promise入门级介绍 本文是观看了慕课网上的进击的NodeJs(二)后写的小结,感谢Scott老师 本文只为了...

  • 35_谈谈你对promise的用法和理解

    一、初识Promise 1、什么是promise? Promise可能大家都不陌生,因为Promise规范已经出来...

  • promise

    初识Promise var promiseCount = 0 function testPromise() { ...

  • 初识Promise

    这是一篇很初级的有关Promise的知识整理,还有很多的知识点正在进行中... 什么是Promise Promis...

  • 初识promise

    Promise是ES6新出的一个构造函数,最主要的就是为了解决回调地狱的问题。Promise三个状态:pendin...

  • 初识Promise

    MDN解释Promise: 1、promise用作异步计算; 2、一个promise实例表示现在存在、将来存在或者...

  • 《Promise》

    1、初识Promise Promise 是异步操作的一种解决方案Promise 一般用来解决层层嵌套的回调函数(回...

  • promise初识及使用

    Promise 是异步编程的一种解决方案,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作...

  • 模拟实现 Promise(小白版)

    模拟实现 Promise(小白版) 本篇来讲讲如何模拟实现一个 Promise 的基本功能,网上这类文章已经很多,...

  • 第八周第二天笔记

    ES6之Promise类 1 Promise类基础知识解读 promise类的静态属性方法分类:resolve()...

网友评论

    本文标题:8.NodeJs之小白初识promise

    本文链接:https://www.haomeiwen.com/subject/cidpbttx.html