资讯专栏INFORMATION COLUMN

深入学习Promise调用链

tianren124 / 700人阅读

摘要:前言使用中,链式的调用对于控制异步执行很重要。的链式调用是支持链式调用的,但是它是不同于上面的链式。是调用方法返回自身,但是是调用方法后返回一个新的。的运行机制请参考的运行机制值穿透由于通过没有成功添加回调函数,发生了值穿透。

前言

使用Promise中,链式的调用对于控制异步执行很重要。

链式调用

在jQuery的使用中,我们常常使用下面的代码

$("#app").show().css("color","red");

这是因为jQuery的对象在调用上述方法的时候,会return此对象本身, 以方便后面可以继续调用此对象的方法。

jQuery.fn.css = function(prop, value) {
    ......
    return this;
}

jQuery.fn.show = function() {
    ......
    return this;
}
Promise的链式调用

Promise是支持链式调用的,但是它是不同于上面jQuery的链式。jQeury是调用方法返回自身,但是Promise是调用方法后返回一个新的Promise。

const promise = new Promise((resolve, reject) => {
    resolve("ok");
})

const promise$1 = promise.then(() => {console.log()});

promise$1 === promise // false

可以看到上面的promise$1是不等于promise的,如果可以在node.js 或者在浏览器中进行断点调试的话,还能看到promise$1的初始化状态是pending的。

当Promise的实例使用then, catch, finally添加完回调方法以后,会返回一个初始化状态为pending的Promise的实例对象。此对象的状态我们在外部的程序是无法进行改变的,它的状态取决于前面所注册的回调方法的执行情况。 当回调方法运行正常,没有产生错误或者异常,返回的值除Promise实例与本身(返回本身将会报错),返回的Promise的实例对象状态会变成resolved, 如果有错误或者异常,则会把状态变为rejected。当然了返回值是Promise的实例对象,那么次Promise实例对象的状态取决于返回的Promise实例对象的状态。

下图以then为例展示promise链式调用运行的流程

示例分析
1. 调用链then的执行顺序
const promise$0 = Promise.resolve("resolve_0");
const promise$1 = new Promise((resolve, reject) => {resolve("resolve_1")})
promise$0.then((val) => { console.log(val) }).then(() => { console.log("continue") });
promise$1.then((val) => { console.log(val) });       
       
//输出结果: resolve_0  resolve_1  continue

promise$0与promise$1在使用then添加回掉函数之前,状态已经从pending变为resolved,它们添加的回掉函数会被立即添加到Promise的运行队列,promise$0.then((val) => { console.log(val) })返回的Promise实例需要等待所注册的回调函数成功执行完毕以后,此Promise的状态才从pending变为resolved。 Promise的运行机制请参考: Promise的运行机制

2. 值穿透
const promise = Promise.resolve("ok");

promise.then().then((val) => {console.log(val)});

// ok

由于promise通过then没有成功添加回调函数,发生了值穿透。

3. 状态传递
const promise = Promise.resolve("complete");

promise.then((val) => { 
    return new Promise ((resolve) => { 
             resolve(val)
            console.log(val, 1); 
        })
    })
    .then((val) => {console.log(val, 2)})
// complete 1 complete 2

我们把Promise暂命名(Pa), 通过promise.then返回的Promise(暂命名Pb), Pb状态需要根据Pathen所注册回调方法的运行,其回调方法返回一个新的Promise(暂命名Pc),由于返回的是Promise。Pb的状态变成取决于Pc的状态, 当Pc的状态变化为resolved以后,Pb的状态也变化为resolved。

4. 巧妙的异常处理
var promise = Promise.resolve("ok");

promise.then(() => {
    throw new Error("error");
}).then(() => {
    console.log("continue");
}).then(() => {
    console.log("again");
}).catch(() => {

}).then(() => {
  console.log("completed")
})
// completed

在then所注册的回调方法,发生异常以后,后续的Promise调用链的状态都是rejected,导致后续的then(resolve)不会被推入Promise的运行队列,也就不会被运行,直到这个错误被then(,reject) 或者catch捕获。 而使用(then(,reject)) 或者catch注册回调方法又会返回一个新的Promise,此Promise的状态又只与它们所注册的回调方法的执行相关。不会受到前面的影响。

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

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

相关文章

  • JS笔记

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

    rottengeek 评论0 收藏0
  • 一起来学Promise

    摘要:参数如前面所提到的,方法只是方法的一个语法糖,原因就在于方法的参数为实际上是两个回调函数,分别用于处理调用它的对象的和状态,而方法就等价于状态处理函数。对象状态传递和改变的方法利用回调的返回值,可以控制某个操作后方法返回的对象及其状态。 注意,本文主要针对ES6标准实现的Promise语法进行阐述,实例代码也都使用ES6语法,快速入门ES6请参见ECMAScript 6 扫盲。 一分钟...

    liaoyg8023 评论0 收藏0
  • JavaScript是如何工作的:事件循环和异步编程的崛起+ 5种使用 async/await 更

    摘要:事件循环从回调队列中获取并将其推入调用堆栈。执行从调用堆栈中移除从调用堆栈中移除快速回顾值得注意的是,指定了事件循环应该如何工作,这意味着在技术上它属于引擎的职责范围,不再仅仅扮演宿主环境的角色。 此篇是 JavaScript是如何工作的第四篇,其它三篇可以看这里: JavaScript是如何工作的:引擎,运行时和调用堆栈的概述! JavaScript是如何工作的:深入V8引擎&编写...

    Honwhy 评论0 收藏0
  • JavasScript重难点知识

    摘要:忍者级别的函数操作对于什么是匿名函数,这里就不做过多介绍了。我们需要知道的是,对于而言,匿名函数是一个很重要且具有逻辑性的特性。通常,匿名函数的使用情况是创建一个供以后使用的函数。 JS 中的递归 递归, 递归基础, 斐波那契数列, 使用递归方式深拷贝, 自定义事件添加 这一次,彻底弄懂 JavaScript 执行机制 本文的目的就是要保证你彻底弄懂javascript的执行机制,如果...

    forsigner 评论0 收藏0
  • 深入理解ES6笔记(十一)Promise与异步编程

    摘要:回调函数模式类似于事件模型,因为异步代码也会在后面的一个时间点才执行如果回调过多,会陷入回调地狱基础可以当做是一个占位符,表示异步操作的执行结果。函数可以返回一个,而不必订阅一个事件或者向函数传递一个回调函数。 主要知识点:Promise生命周期、Promise基本操作、Promise链、响应多个Promise以及集成PromiseshowImg(https://segmentfaul...

    RayKr 评论0 收藏0

发表评论

0条评论

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