资讯专栏INFORMATION COLUMN

20170702-异步编程之Promise

gecko23 / 1002人阅读

摘要:异步操作成果异步操作失败方法可以接受两个回调函数作为参数。第一个回调函数完成以后,会将返回结果作为参数,传入第二个回调函数。等同于等同于这段代码会让这个对象立即进入状态,并将错误对象传递给指定的回调函数。

1.Promise的含义

Promise是异步编程的一种解决方案

Promise实例代表一个异步操作,从它可以获取异步操作的消息

Promise实例有三种状态:

Pending:进行中

Resolved:已完成

Rejected:已失败

Promise实例的状态只能由 Pending->ResolvedPending->Rejected。一旦Promise实例的状态发生改变,就不会再发生变化,任何时候都可以得到这个结果

为什么要使用Promise:通过Promise,可以将一步操作以同步操作的流程表达出来,可以避免层层嵌套的回调函数(回调地域),并且Promise提供了统一的接口,使得控制异步操作更加容易

2.Promise构造函数

Promise是一个构造函数,用来生成Promise实例

var promise = new Promise(function(resolve, reject)){
    // ... do something
    if (/*异步操作成果*/) {
        resolve(value)
    } else { /*异步操作失败*/
        reject(error)
    }
}

Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolvereject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。

resolve函数的作用是,将Promise实例的状态从“未完成”变为“成功”(即从 Pending 变为 Resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去

reject函数的作用是,将Promise实例的状态从“未完成”变为“失败”(即从 Pending 变为 Rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去**

Promise.prototype.then()

Promise实例生成以后,可以用then方法分别指定Resolved状态和Reject状态的回调函数。

var promise = new Promise(function(resolve, reject)){
    // ... do something
    if (/*异步操作成果*/) {
        resolve(value)
    } else { /*异步操作失败*/
        reject(error)
    }
}
promise.then(function(value) {
  // success
}, function(error) {
  // failure
});

then方法可以接受两个回调函数作为参数。第一个回调函数是Promise的状态变为Resolved时调用,第二个回调函数是Promise实例的状态变为Rejected时调用。其中,第二个函数是可选的,不一定要提供。

这两个函数都接受Promise实例传出的值作为参数。(简单地说就是:上面的promise对象在处理异步操作的过程中,如果调用了resolve方法,则会将resolve的参数传递给then方法的第一个函数,如果调用了reject方法,这会将reject的参数传递给then方法的第二个函数)

then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例),因此可以采用链式写法,即then方法后面在调用另一个then方法

上面的代码使用then方法,依次指定了两个回调函数。第一个回调函数完成以后,会将返回结果作为参数,传入第二个回调函数。(实际上是第一个then方法返回了一个Promise实例,在该实例中调用了resolve方法,而json.post则是作为resolve的参数)

上面代码中,第一个then方法指定的回调函数,返回的是另一个Promise实例,则第一个then方法会直接将该Promise实例返回

Promise.prototype.catch()

该方法是.then(undefined, onRejected)的别名,用于指定发生错误时的回调函数。

promise.then(function(data) {
    console.log("success");
}).catch(function(error) {
    console.log("error", error);
});

promise对象的错误,会一直向后传递,直到被捕获。即错误总会被下一个catch所捕获。then方法指定的回调函数,若抛出错误,也会被下一个catch捕获。catch中也能抛错,则需要后面的catch来捕获。

sendRequest("test.html").then(function(data1) {
    //do something
}).then(function (data2) {
    //do something
}).catch(function (error) {
    //处理前面三个Promise产生的错误
});
Promise.all()

该方法用于将多个Promise实例,包装成一个新的Promise实例

// p1,p2,p3都是promise实例
var p = Promise.all([p1, p2, p3]);

新的Promise实例的状态由三个promise实例共同决定

当三个promise实例的状态都变为fulfilled,p的状态才会变为fulfilled,并将三个promise返回的结果,按照参数顺序存入数组,传给p的回调函数

当p1, p2, p3其中之一状态变为rejected,p的状态也会变为rejected,并把第一个被reject的promise的返回值,传给p的回调函数

Promise..race()

该方法用于将多个Promise实例,包装成一个新的Promise实例

// p1,p2,p3都是promise实例
var p = Promise.race([p1, p2, p3]);

新的Promise实例的状态由三个promise实例共同决定

当p1, p2, p3其中之一状态发生改变(变为fulfilled或者rejected),p的状态也会随之改变,并把第一个改变状态的promise的返回值,传给p的回调函数

Promise.resolve()

Promise.resolve方法的参数分为四种情况

参数是一个Promise实例

如果参数是Promise实例,那么Promise.resolve将不做任何修改、原封不动地返回这个实例。

参数是一个thenable对象

let thenable = {
  then: function(resolve, reject) {
    resolve(42);
  }
};

let p1 = Promise.resolve(thenable);
p1.then(function(value) {
  console.log(value);  // 42
});

Promise.resolve方法会将这个对象转为Promise对象,然后就立即执行thenable对象的then方法。

参数不是具有then方法的对象,或根本就不是对象

如果参数是一个原始值,或者是一个不具有then方法的对象,则Promise.resolve方法返回一个新的Promise对象,状态为Resolved。

Promise.resolve("Success");

/*******等同于*******/
new Promise(function (resolve) {
    resolve("Success");
});

不带任何参数

直接返回一个Resolved状态的Promise对象。

Promise.resolve("Success");

/*******等同于*******/
new Promise(function (resolve) {
    resolve();
});
Promise.reject()
Promise.reject(new Error("error"));

/*******等同于*******/
new Promise(function (resolve, reject) {
    reject(new Error("error"));
});

这段代码会让这个Promise对象立即进入rejected状态,并将错误对象传递给then指定的onRejected回调函数。

参考资料

ECMAScript 6 入门

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

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

相关文章

  • 20170702-异步编程 async await

    摘要:是异步编程的另一种解决方案函数是对函数的改进的基本用法函数函数返回一个实例,可以使用方法为返回的实例添加回调函数。函数内部语句返回的值,会成为方法回调函数的参数。也就是说,只有函数内部的异步操作执行完,才会执行方法指定的回调函数。 async await async await是异步编程的另一种解决方案 async函数是对Generator函数的改进 async的基本用法 asyn...

    StonePanda 评论0 收藏0
  • 2017-07-03 前端日报

    摘要:前端日报精选使用可变数据结构知乎专栏我接触过的前端数据结构与算法人人网博客基于指令和混合的前端通用埋点方案知乎专栏的数据依赖实现原理简析从到掘金中文第期升级指南译是什么鬼知乎专栏异步编程之每日技术笔记的个特性以及对的展 2017-07-03 前端日报 精选 Redux 使用可变数据结构 - 知乎专栏我接触过的前端数据结构与算法 – 人人网FED博客基于指令和混合的前端通用埋点方案 - ...

    animabear 评论0 收藏0
  • JS异步编程Promise

    摘要:三是控制反转控制权在其他人的代码上,假如异步函数是别人提供的库,我们把回调函数传进去,我们并不能知道异步函数在调用回调函数之外做了什么事情。错误捕捉相比回调函数的错误无法在外部捕捉的问题,能够为一连串的异步调用提供错误处理。 前言 《JS异步编程之 callback》一文我们了解了JS 是基于单线程事件循环的概念构建的,回调函数不会立即执行,由事件轮询去检测事件是否执行完毕,当执行完有...

    Hegel_Gu 评论0 收藏0
  • ES6 异步编程二:Promise

    摘要:今天对于处理异步调用已经有了很多成熟的方案,在我看来这些方案都无外乎在解决一个问题如何能看似顺序地传递异步调用的结果,本文要说的就是原生提供的一个解决方案。在对进行叙述之前,依旧引用阮大的入门一书中的章节便于大家更严谨和全面的学习和参考。 异步回调的泥潭 异步回调是最直接的异步结果处理模式,将一个回调函数callback扔进异步处理函数中,当异步处理获得结果之后再调用这个回调函数就可以...

    Gilbertat 评论0 收藏0
  • JS笔记

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

    rottengeek 评论0 收藏0

发表评论

0条评论

gecko23

|高级讲师

TA的文章

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