嗨,了解一下,个人Promise学习笔记

Promise

Promise 是什么?

词语本意:

发音:[ˈprɒmɪs]
词性:名词,
翻译:许诺,允诺。

MDN解释

  1. Promise 对象用于一个异步操做。
  2. 一个Promise表示一个如今,未来或永不可能可用的值。

按照书写方式来解释

能够将异步操做的书写方式变成一种队列化的书写方式,并按照咱们写的那样的预期来执行返回符合预期的结果。javascript

为何须要Promise

js为检查表单而生,其首要目标是操做dom,界面冻结会形成很是不友好的用户体验,因此dom操做大可能是异步的。
注意:同步操做的处理器未执行完成会使得界面没法响应用户的其余操做,而异步操做则能够避免该问题。
常见的异步操做语法:java

1. 异步事件

$('#start').on('click',startHandler);
function startHandler(){} // 定义事件响应的处理器函数

用户点击start元素就会触发一个异步事件去执行,再次触发没必要等待前一次事件执行完成,就能够再次触发。node

2. 回调函数

$.ajax('http://baidu.com',{
    success:function(res){
    // 成功回调处理器
    },
    error:function(e){
    // 失败回调处理器
    }
});

用户发送一个向百度服务器获取数据的异步请求ajax

3. 无阻塞高并发的node的诞生

更加严重的依赖异步操做才能完成无阻赛高并发的特性。数组

然而异步回调这种方式并非理想的,它却有一些问题,
好比:promise

  1. 回调地狱这种难于维护的书写方式。

更深层次的问题:服务器

  1. 嵌套回调中的循环语句出错后,没法正常的使用return和throw终止
  2. 没法正常检索堆栈信息(每个回调都会从新创建堆栈)
  3. 多个回调之间难以创建联系

Promise详解

一个promise的基本使用案例:并发

new Promise(
    // 执行器 executor
    function ( resolve, reject ) {
        //一段耗时很长的异步操做
        resolve(); //异步处理成功
        reject(); // 异步处理失败 
        //注意:resolve和reject这俩个回调函数被调用是互斥的  
    }
).then( function A(){
            //成功,下一步
    }, 
    function B(){
        //失败,作善后处理
    } 
);
  1. promise是一个代理对象,它和原先要进行的操做并没有关系。
  2. 它经过引入一个回调,避免更多的回调。
promise有三个状态:

pending 初始状态 fulfilled 操做成功 rejectd 操做失败dom

  1. promise一经建立,执行器便会马上执行;
  2. 异步操做经过调用resolve改变promise状态为fulfilled,经过调用reject改变promise状态为rejected;
  3. promise状态发生改变就会触发then里面的响应函数;
  4. promise状态一经改变,不会再变。
promise最简单的实现:
//范例1
console.log('here we go');
new Promise( resolve => {
    setTimeout( () => {
        resolve('hello');
    }, 2000);
}).then( value => {
    console.log( value + ' world');
});
/* 控制台日志 */ 
here we go
// 2s之后
hello world
// 范例2
console.log('here we go');
new Promise(resolve => {
    setTimeout( () => {
        resolve('hello');
    }, 2000);
}).then(value => {
    console.log(value);
    return new Promise( resolve => {
        setTimeout(() => {
            resolve('world');
        }, 2000);
    });
}).then(value => {
    console.log( value + ' world');
});
/* 控制台日志 */
here we go
// 2s后
hello
// 2s后
world world

// 假如一个Promise已经完成了,再.then()会怎样?异步

console.log('start');
let promise = new Promise(resolve => {
    setTimeout(() => {
        console.log('the promise fulfilled');
        resolve('hello, world');
    }, 1000);
});
setTimeout(() => {
    promise.then( value => {
        console.log(value);
    });
}, 3000);
/* 控制台 */
17:37:29.015 start
17:37:30.016 the promise fulfilled
17:37:32.017 hello, world

// 假如在.then()的函数里面不返回新的Promise,会怎样?

console.log('here we go');
new Promise(resolve => {
    setTimeout( () => {
        resolve('hello');
    }, 2000);
}).then( value => {
    console.log(value);
    console.log('everyone');
    (function () {
        return new Promise(resolve => {
            setTimeout(() => {
                console.log('Mr.Laurence');
                resolve('Merry Xmas');
            }, 2000);
        });
    }());
//     return false;
}).then( value => {
    console.log(value + ' world'); return 0
}).then( value => {
    console.log(value + ' world');
}).then( value => {
    console.log(value + ' world');
});
/* 控制台 */
17:53:03.175 here we go
17:53:03.191 Promise {<pending>}
17:53:05.181 hello
17:53:05.181 everyone
17:53:05.181 undefined world
17:53:05.182 0 world
17:53:05.182 undefined world
17:53:07.187 Mr.Laurence
从日志能够看出,
1. 执行器中必须回调resolve或者reject改变promise的状态;
2. 当状态改变后继续调用then方法,可是promise中的状态已经没法改变了;
3. 能够看到promise对象帮咱们生成了一个队列,这个队列一直存在。
then方法
  1. then() 接受俩个状态响应函数参数,分别表明fulfilled和rejected
  2. then() 返回一个新的Promise实例,因此它能够链式调用
  3. 状态响应函数能够返回新的Promise,其余值,或者不返回值
  4. 若是返回新的Promise,那么下一级.then()会在新的promise状态改变以后执行
  5. 若是返回其它任何值,则会马上执行下一级.then()
  6. then里面有then的状况
    1). 由于.then()返回的仍是Promise实例。
    2). 会等里面的.then()执行完,在执行外面的。
    3). 对咱们来讲,此时最好将其展开,会更好阅读。

测试
问题:下面四种Promise的区别是什么?

前提:doSomething方法和doSomethingElse方法均返回一个promise实例。
// #1
doSomething().then(function() {
    return doSomethingElse();
});
// #2
doSomething().then(function(){
    doSomethingElse();
});
// #3
doSomething().then(doSomethingElse());
// #4
doSomething().then(doSomethingElse);
// 解析:
// #1
doSomething().then(function() {
    return doSomethingElse();
});
//符合预期的,能够继续回调then方法获取doSomethingElse的结果
// #2
doSomething().then(function(){
    doSomethingElse();
});
//then中没有返回promise,因此以后的then没法获取到doSomethingElse的结果,而且与doSomethingElse几乎同时执行
// #3
doSomething().then(doSomethingElse());
// then应该接收一个状态处理函数,当前这种状况传入了一个promise实例,没法获取上层promise的结果,而该层then会被忽略,下一层会获取到doSomething()的结果
// #4
doSomething().then(doSomethingElse);
// then方法中吧doSomethingElse直接当成状态处理函数也是能够达到预期的
错误处理 catch方法

catch和then同样会返回一个promise实例。若是没有抛出错误,该实例默认也会返回fulfilled状态。

Promise 经常使用函数

promise.all
接收一个数组参数,返回一个新的promise实例,响应函数中的结果为数组中的每一个promise的结果。
与map连用
使用forEach和reduce实现队列
ES2017 的async/await

该学习笔记是学习慕课网中 Promise入门 记录

相关文章
相关标签/搜索