资讯专栏INFORMATION COLUMN

关于promise的小结

Tony_Zby / 1275人阅读

摘要:则是把类似的异步处理对象和处理规则进行规范化,并按照采用统一的接口来编写,而采取规定方法之外的写法都会出错。这个对象有一个方法,指定回调函数,用于在异步操作执行完后执行回调函数处理。到目前为止,已经学习了创建对象和用,方法来注册回调函数。

Promise

本文从js的异步处理出发,引入Promise的概念,并且介绍Promise对象以及其API方法。

js里的异步处理

可以参考这篇文章
js是单线程的,
在js里,异步处理总共有四种方法,其中最常见的一种方法是采用回调函数的方式

function f1(callback){
    setTimeout(function(){
        callback();
    },1000)
}

f1(f2);

另外除了回调函数,事件监听的机制也会进行异步处理。任务的执行不取决于代码的顺序,而是取决于事件是否会发生。

如果是业务逻辑不复杂还好说,可是如果业务逻辑很复杂的话,回调嵌套的很多,代码书写起来会变得很复杂很难看懂。
还有一个问题是,如果有多个异步操作,那么就存在一个处理顺序的问题,代码如何按照希望的顺序执行。

Promise 简介

Promise是抽象异步处理对象以及对其进行各种操作的组件。Promise并不是从js里出现的概念。
Promise则是把类似的异步处理对象和处理规则进行规范化, 并按照采用统一的接口来编写,而采取规定方法之外的写法都会出错。

首先说,Promise是一个对象,所以说这个对象与js里的其他对象没什么不一样的。要说与众不同的地方时,Promise对象充当代理的作用,充当异步操作和回调函数之间的中介

Promise的思想是:每次执行一个异步操作以后,立刻返回一个Promise对象,因为是立刻操作,所以我们可以进行同步操作流程。这个Promise对象有一个then方法,指定回调函数,用于在异步操作执行完后执行回调函数处理。

//换成Promise的写法
new Promise(f5).then(f4).then(f3).then(f2).then(f1)

使用Promise,用同步的写法处理异步操作的代码,使得代码清晰易懂,等一个异步函数处理完成之后,才会执行下一个then里边的函数。这样就避免了前边的多个回调可能引发的顺序问题。

Promise接口

前边说过,Promise接口的作用是,返回一个Promise对象。
一个Promise对象有三种状态

pending 异步操作未完成

resolve 异步操作已成功完成

reject 异步操作失败

至于这三种关系的途径可以描述为两种

pending ---> resolve
pending ---> reject

这种变化只会出现一次。所以,意思是,一个异步操作结束之后只会有两种状态,成功or失败。异步操作成功时,Promise对象返回一个值,对象状态变为resolve,异步操作失败时,对象状态变为reject。

Promise对象用then方法添加回调函数,then方法支持链式调用。

promise.then(onFulfilled, onRejected)

then方法接受两个参数,看名字就知道第一个参数是Promise对象状态时resolve的时候调用,而第二个参数可以省略,表示Promise调用失败状态是reject的时候执行这个回调。

除了then方法,还有一个专门处理异常的方法.
.catch 也可以理解为 promise.then(undefined, onRejected) 。

promise.catch(onRejected)

then和catch两个方法是写到了Promise对象的原型上的,每个Promise对象都可以调用。

Promise对象的生成

ES6提供了原生的Promise对象构造函数,用于生成Promise对象,

var promise = new Promise(function(resolve, reject){
  // 异步操作的代码

  if (/* 异步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});

Promise对象接收一个函数作为构造函数的参数,这个函数同样有两个参数,这两个参数是由js引擎提供的函数,不用自己来部署。
resolve函数的作用是把Promise对象的状态从pending变为resolve,在异步操作成功的时候调用,并且将异步操作的结果作为参数传过去。同样的,reject函数的作用是把对象状态从pending变成reject,在失败的时候调用,并且传递结果参数。

接下来,当Promise对象创建成功之后就可以用then方法链式调用了。

Promise对象其他方法
1.Promise.resolve()

一般情况下,我们会用构造函数的方法创建Promise对象。但是,除此之外我们也会有其他方法创建。
静态方法Promise.resolve(value)被认为是new Promise方式创建Promise对象的快捷方式。

Promise.resolve(42).then(function(value){
    console.log(value);
})

resolve()会让对象状态立即变成resolved,并且将形参立刻传给下一个回调。

2.Promise.reject()

这个方法类似上一个方法,也是创建Promise对象的快捷方式,但是只会把Promise对象从pending变为rejected。参数是一个异常对象,传递给下一个catch方法或者then方法。

Promise.reject(new Error("BOOM!")).catch(function(error){
    console.error(error);
});
3.Promise.all() && Promise.race()

到目前为止,已经学习了创建Promise对象和用then,catch方法来注册回调函数。如果只有一个Promise对象的话很好说,但是如果有多个Promise对象的时候要如何处理呢。

Promise.all 接收一个 promise对象的数组作为参数,当这个数组里的所有promise对象全部变为resolve或reject状态的时候,它才会去调用 .then 方法。

Promise.race 只要有一个promise对象进入 FulFilled 或者 Rejected 状态的话,就会继续进行后面的处理。

4. 每次调用then都会返回一个新创建的promise对象
function f1(v){
    console.log(v);
    return 2;
}
function f2(v){
    console.log(v)
}
Promise.resolve(1).then(f1).then(f2);

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

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

相关文章

  • 关于vue、vuex一些初步小结

    摘要:只能是同步函数,原因是无法捕捉异步函数的快照。除了这三个概念外,还有类比计算属性,用于从派生出一些值分割较大的状态树,便于管理。处理表单可手动监听或是使用带的双向绑定计算属性。 一、Vue组件的创建 一般语法: Vue.component(tagName, options) 务必在根组件实例化之前注册组件 组件options说明: data: 必须是一个函数,目的在于返回独立的对象...

    joywek 评论0 收藏0
  • 2018.11.19秋招末第二波前端实习/校招小结

    摘要:背景个人背景就读于东北某普通二本院校计算机软件工程专业,现大四,北京实习前端方向,自学,技术栈时间背景大概是在月日准备好简历开始投递秋招差不多已经结束招聘岗位不多,投递对象为大一些的互联网公司事件背景第一个入职的是好未来的前端实习岗,待遇工 背景 个人背景 就读于东北某普通二本院校计算机软件工程专业,现大四,北京实习 前端方向,自学,vue技术栈 时间背景 大概是在11月9日准备...

    suxier 评论0 收藏0
  • 2018.11.19秋招末第二波前端实习/校招小结

    摘要:背景个人背景就读于东北某普通二本院校计算机软件工程专业,现大四,北京实习前端方向,自学,技术栈时间背景大概是在月日准备好简历开始投递秋招差不多已经结束招聘岗位不多,投递对象为大一些的互联网公司事件背景第一个入职的是好未来的前端实习岗,待遇工 背景 个人背景 就读于东北某普通二本院校计算机软件工程专业,现大四,北京实习 前端方向,自学,vue技术栈 时间背景 大概是在11月9日准备...

    canger 评论0 收藏0
  • 【个人向整理】Promise

    摘要:方法而对象本身,有一些方法查看的原型,发现它内置有几个方法参数处理成功的函数,处理错误的函数返回值返回一个对象,所以可以链式调用。参数返回值的参数应该是函数,传入非函数则会发生值穿透。 前言 网上关于Promise的文章确实是非常多了,但是自己实践的并不多,这里是针对自己的一个知识点小结和梳理,当然啦如果有错误欢迎提出^_^。 初定义 定义:Promise对象用于一个异步操作的最终完成...

    2bdenny 评论0 收藏0
  • 2015 年度小结(技术方面)

    摘要:因为路由层面受业务影响很大,经常修改一些功能的行为,所以后来大部分测试都是针对层面的单元测试。在我了解的过程中,我发现中文网络上对的讨论非常分散,于是我创建了中文社区,到年末已经有个注册用户和个帖子了。 https://jysperm.me/2016/02/programming-of-2015/ 从 2014 年末开始开发的一个互联网金融项目终于在今年三月份上线了,这是一个 Node...

    宋华 评论0 收藏0

发表评论

0条评论

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