资讯专栏INFORMATION COLUMN

嗨,了解一下,我的Promise学习笔记

yanest / 2752人阅读

摘要:回调函数成功回调处理器失败回调处理器用户发送一个向百度服务器获取数据的异步请求无阻塞高并发的的诞生更加严重的依赖异步操作才能完成无阻赛高并发的特性。

Promise Promise 是什么? 词语本意:
发音:[ˈprɒmɪs]
词性:名词,
翻译:许诺,允诺。
MDN解释

Promise 对象用于一个异步操作。

一个Promise表示一个现在,将来或永不可能可用的值。

按照书写方式来解释

可以将异步操作的书写方式变成一种队列化的书写方式,并按照我们写的那样的预期来执行返回符合预期的结果。

为什么需要Promise

js为检查表单而生,其首要目标是操作dom,界面冻结会造成非常不友好的用户体验,所以dom操作大多是异步的。
注意:同步操作的处理器未执行完成会使得界面无法响应用户的其他操作,而异步操作则可以避免该问题。
常见的异步操作语法:

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

用户点击start元素就会触发一个异步事件去执行,再次触发不必等待前一次事件执行完成,就可以再次触发。

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

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

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

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

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

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

更深层次的问题:

嵌套回调中的循环语句出错后,无法正常的使用return和throw终止

无法正常检索堆栈信息(每一个回调都会重新建立堆栈)

多个回调之间难以建立联系

Promise详解

一个promise的基本使用案例:

new Promise(
    // 执行器 executor
    function ( resolve, reject ) {
        //一段耗时很长的异步操作
        resolve(); //异步处理成功
        reject(); // 异步处理失败 
        //注意:resolve和reject这俩个回调函数被调用是互斥的  
    }
).then( function A(){
            //成功,下一步
    }, 
    function B(){
        //失败,做善后处理
    } 
);

promise是一个代理对象,它和原先要进行的操作并无关系。

它通过引入一个回调,避免更多的回调。

promise有三个状态:

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

promise一经创建,执行器便会立刻执行;

异步操作通过调用resolve改变promise状态为fulfilled,通过调用reject改变promise状态为rejected;

promise状态发生改变就会触发then里面的响应函数;

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 {}
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方法

then() 接受俩个状态响应函数参数,分别代表fulfilled和rejected

then() 返回一个新的Promise实例,所以它可以链式调用

状态响应函数可以返回新的Promise,其他值,或者不返回值

如果返回新的Promise,那么下一级.then()会在新的promise状态改变之后执行

如果返回其它任何值,则会立刻执行下一级.then()

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入门 记录

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/94295.html

相关文章

  • 爱奇艺小程序陪你一夏

    摘要:只要滑动了就会触发,并且有一个代表当时滑动到第几个。可能有一点笨笨的。 前言 在炎热的夏天里最美滋滋的事情是什么呢,我觉得当然是宅在家里,吹着空调,吃着零食看电视剧电影里的帅气小哥哥、漂亮小姐姐了!在闲暇时光我会经常用爱奇艺小程序看视频,加上现在已经学习了一段时间小程序了,啪,动手模仿一个爱奇艺视频小程序的念头就产生了。虽然现在还是个小白,但是希望在这趟爱奇艺小程序之旅上为各位乘客朋友...

    edagarli 评论0 收藏0
  • 前端文档收集

    摘要:系列种优化页面加载速度的方法随笔分类中个最重要的技术点常用整理网页性能管理详解离线缓存简介系列编写高性能有趣的原生数组函数数据访问性能优化方案实现的大排序算法一怪对象常用方法函数收集数组的操作面向对象和原型继承中关键词的优雅解释浅谈系列 H5系列 10种优化页面加载速度的方法 随笔分类 - HTML5 HTML5中40个最重要的技术点 常用meta整理 网页性能管理详解 HTML5 ...

    jsbintask 评论0 收藏0
  • 前端文档收集

    摘要:系列种优化页面加载速度的方法随笔分类中个最重要的技术点常用整理网页性能管理详解离线缓存简介系列编写高性能有趣的原生数组函数数据访问性能优化方案实现的大排序算法一怪对象常用方法函数收集数组的操作面向对象和原型继承中关键词的优雅解释浅谈系列 H5系列 10种优化页面加载速度的方法 随笔分类 - HTML5 HTML5中40个最重要的技术点 常用meta整理 网页性能管理详解 HTML5 ...

    muddyway 评论0 收藏0
  • JS笔记

    摘要:从最开始的到封装后的都在试图解决异步编程过程中的问题。为了让编程更美好,我们就需要引入来降低异步编程的复杂性。异步编程入门的全称是前端经典面试题从输入到页面加载发生了什么这是一篇开发的科普类文章,涉及到优化等多个方面。 TypeScript 入门教程 从 JavaScript 程序员的角度总结思考,循序渐进的理解 TypeScript。 网络基础知识之 HTTP 协议 详细介绍 HTT...

    rottengeek 评论0 收藏0

发表评论

0条评论

yanest

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<