本文是借鉴于ac黄的博客。

接触es6也有几个月了,貌似没有系统的去学习过它,总是用到什么,查查什么。今天就说下es6中的promise对象。

先说说promise解决了什么问题?

写前端的同学都经常遇到这种问题:在多个接口异步请求数据,然后利用这些数据来进行一系列的操作。一般如下实现:

$.ajax({
url: '......',
success: function (data) {
    //基于data,才能进行下发操作
$.ajax({
url: '......',
success: function (data) {
// ......
}
});
}
});

  这样写会导致两个缺点:

  1. 在需要多个操作的时候,会导致多个回调函数嵌套,导致代码不够直观,就是常说的 Callback Hell

  2. 如果几个异步操作之间并没有前后顺序之分(例如不需要前一个请求的结果作为后一个请求的参数)时,同样需要等待上一个操作完成再实行下一个操作。

es6中的Promise对象就来解决这个问题。

何为Promise对象?

一个 Promise 对象可以理解为一次将要执行的操作(常常被用于异步操作),使用了 Promise 对象之后可以用一种链式调用的方式来组织代码,让代码更加直观(解决第1项缺点)。而且由于 Promise.all 这样的方法存在,可以让同时执行多个操作变得简单(解决第2项缺点)。

resolve 和 reject

大家可以用把下方这段代码贴到浏览器开发模式中的console中运行,看看结果。

function helloWorld (ready) {
return new Promise(function (resolve, reject) {
if (ready) {
resolve("Hello World!");
} else {
reject("Good bye!");
}
});
} helloWorld(true).then(function (message) {
alert(message);
}, function (error) {
alert(error);
});  

结果是,浏览器弹出 “hello world!”.

上面的代码实现的功能非常简单,helloWord 函数接受一个参数,如果为 true 就打印 "Hello World!",如果为 false 就打印错误的信息。helloWord 函数返回的是一个 Promise 对象。

在 Promise 对象当中有两个重要方法————resolve 和 reject

resolve 方法可以使 Promise 对象的状态改变成成功,同时传递一个参数用于后续成功后的操作,在这个例子当中就是 Hello World! 字符串。

reject 方法则是将 Promise 对象的状态改变为失败,同时将错误的信息传递到后续错误处理的操作。

Promise 对象有三种状态:

  • Fulfilled 可以理解为成功的状态

  • Rejected 可以理解为失败的状态

  • Pending 既不是 Fulfilld 也不是 Rejected 的状态,可以理解为 Promise 对象实例创建时候的初始状态

helloWorld 的例子中的 then 方法就是根据 Promise 对象的状态来确定执行的操作,resolve 时执行第一个函数(onFulfilled),reject 时执行第二个函数(onRejected)。

then 和 catch

then

helloWorld 的例子当中利用了 then(onFulfilld, onRejected) 方法来执行一个任务打印 "Hello World!",在多个任务的情况下 then方法同样可以用一个清晰的方式完成。

例如:

function printHello (ready) {
return new Promise(function (resolve, reject) {
if (ready) {
resolve("Hello");
} else {
reject("Good bye!");
}
});
} function printWorld () {
alert("World");
} function printExclamation () {
alert("!");
} printHello(true)
.then(function(message){
alert(message);
})
.then(printWorld)
.then(printExclamation);

  结果是顺序弹出:“Hello”“World”“!”

then 可以使用链式调用的写法原因在于,每一次执行该方法时总是会返回一个 Promise 对象。另外,在 then onFulfilled 的函数当中的返回值,可以作为后续操作的参数。因此上面的方法可以写为:

function printHello (ready) {
return new Promise(function (resolve, reject) {
if (ready) {
resolve("Hello");
} else {
reject("Good bye!");
}
});
} printHello(true).then(function (message) {
return message;
}).then(function (message) {
return message + ' World';
}).then(function (message) {
return message + '!';
}).then(function (message) {
alert(message);
});

  结果输出是:“Hello World!”。

catch

catch 方法是 then(onFulfilled, onRejected) 方法当中 onRejected 函数的一个简单的写法,也就是说可以写成 then(fn).catch(fn),相当于 then(fn).then(null, fn)。使用 catch 的写法比一般的写法更加清晰明确。

Promise.all 和 Promise.race

Promise.all 可以接收一个元素为 Promise 对象的数组作为参数,当这个数组里面所有的 Promise 对象都变为 resolve 时,该方法才会返回。

var p1 = new Promise(function (resolve) {
setTimeout(function () {
resolve("Hello");
}, 3000);
}); var p2 = new Promise(function (resolve) {
setTimeout(function () {
resolve("World");
}, 1000);
}); Promise.all([p1, p2]).then(function (result) {
console.log(result); // ["Hello", "World"]
});

  

上面的例子模拟了传输两个数据需要不同的时长,虽然 p2 的速度比 p1 要快,但是 Promise.all 方法会按照数组里面的顺序将结果返回。

日常开发中经常会遇到这样的需求,在不同的接口请求数据然后拼合成自己所需的数据,通常这些接口之间没有关联(例如不需要前一个接口的数据作为后一个接口的参数),这个时候 Promise.all 方法就可以派上用场了。

Promise.race 和 Promise.all 方法类似,它同样接收一个数组,不同的是只要该数组中的 Promise 对象的状态发生变化(无论是 resolve 还是 reject)该方法都会返回。

兼容性

在浏览器端,一些主流的浏览器都已经可以使用 Promise 对象进行开发,在 Node.js 配合 babel 也可以很方便地使用。

如果要兼容旧的浏览器,建议可以寻找一些第三方的解决方案,例如 jQuery 的 $.Deferred

浅谈es6 promise的更多相关文章

  1. 浅谈ES6原生Promise

    浅谈ES6原生Promise 转载 作者:samchowgo 链接:https://segmentfault.com/a/1190000006708151 ES6标准出炉之前,一个幽灵,回调的幽灵,游 ...

  2. ES6浅谈之Promise

    首先来回想一下Promise对象的写法: // 方法1 let promise = new Promise ( (resolve, reject) => { if ( success ) { . ...

  3. 浅谈ES6基础——Promise

    IMAGE加载 Callback Hell function loadImg(src,callback,fail) { var img = document.createElement('img'); ...

  4. 浅谈ES6新特性

    ES6的了解 新增模板字符串(为JavaScript提供了简单的字符串插值功能).箭头函数(操作符左边为输入的参数,而右边则是进行的操作以及返回的值Inputs=>outputs.).for-o ...

  5. 浅谈 es6 箭头函数, reduce函数介绍

    今天来谈一下箭头函数, es6的新特性 首先我们来看下箭头函数长什么样子, let result = (param1, param2) => param1+param2; 上述代码 按照以前书写 ...

  6. 浅谈ES6

    ECMAScript6.0(简称ES6)是javaScript语言的下一代标准,已经在2015年6月正式发布了.它的目标,使得javaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语言 ...

  7. 浅谈ES6新增数据类型:Symbol

    面试中喜闻乐见的问题就是问我们的ES6新增了哪些个新特性 这篇文章一起学习一下新增的数据类型:Symbol JS的原始数据类型:6种Boolean,String,Undefined,NULL,Numb ...

  8. 浅谈ES6——ES6中let、const、var三者的区别

    在了解let.const.var的区别之前,先了解一些什么是es6 Es6 全称ECMAscript 是JavaScript语言的一个标准,其实Es6本质就是JavaScript的一个版本,为什么叫E ...

  9. 浅谈ES6数组及对象的解构

    一.数组的解构,ES6的新特性,主要是方便操作数组,节省不必要的代码,提高代码质量. 上图例子中, example1: 之前想要获取数组中的值,只能挨个获取下标,然后取值 example2:ES6新特 ...

随机推荐

  1. 【bzoj1787】&【bzoj1832】[Ahoi2008]Meet 紧急集合 & 聚会

    bzoj1787就是bzoj1832 bzoj1832 空间和时间少了一些... 求三个结点到一个结点距离之和最小的结点以及距离和 求出两两lca,其中有两个相同,答案则为另一个 感觉就是一大暴力.. ...

  2. redis Database Eviction Policies Redis on Flash

    Database Eviction Policies - Redis Enterprise Software | Redis Labs https://redislabs.com/redis-ente ...

  3. 2015-2016 ACM-ICPC Pacific Northwest Regional Contest (Div. 2)V - Gears

    Problem V | limit 4 secondsGearsA set of gears is installed on the plane. You are given the center c ...

  4. 逻辑频道号---DVB NIT LCN

    先介绍NIT,NIT描述如下: 有一点要注意,NIT是对大网的描述,即NIT并不是描述当前的流,而是描述大网的某些或者全部流.如下图,TS流描述1-6共对6个频点不同的TS流进行了描述,具体对哪一个流 ...

  5. uva11542

    https://vjudge.net/problem/UVA-11542 xor高斯消元... 答案为2^f-1 其实书上有一个问题 样例有3种情况,其中4,6,15是绑在一起的,也就是他们必须满足一 ...

  6. bzoj4534: 基础排序算法练习题

    传送门     策爷的论文题啊……题解在这儿 我只想知道为什么这题的弱化版会出现在我们今天的%你赛里…… 题意:给你一堆操作$(l,r)$,表示将区间$(l,r)$按升序排序.以及$q$个询问,每次询 ...

  7. golang——database/sql包学习

    1.database/sql包 sql包提供了保证SQL或类SQL数据库的泛用接口. 使用sql包时必须注入(至少)一个数据库驱动. (1)获取mysql driver:go get -v githu ...

  8. (博弈论)51NOD 1072 威佐夫游戏

    有2堆石子.A B两个人轮流拿,A先拿.每次可以从一堆中取任意个或从2堆中取相同数量的石子,但不可不取.拿到最后1颗石子的人获胜.假设A B都非常聪明,拿石子的过程中不会出现失误.给出2堆石子的数量, ...

  9. c#自定义ORM框架---(泛型&反射&实体类扩展属性<附带通用增、删、查、改>)

    该教材主要是运用到泛型.反射和实体类扩展属性 步骤一.建立扩展属性类 实体类扩展属性要继承Attribute基类完成 [AttributeUsage(AttributeTargets.Property ...

  10. jQuery——表单应用(4)

    HTML: <!--复选框应用--> <!DOCTYPE html> <html> <head> <meta charset="UTF- ...