本文是借鉴于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. Codeforces Round #240 (Div. 1) B. Mashmokh and ACM DP

                                                 B. Mashmokh and ACM                                     ...

  2. HTML <iframe> 标签的 src 属性

    HTML <iframe> 标签的 src 属性 <iframe src="/index.html"> <p>Your browser does ...

  3. beego4---web项目结构

    app.conf appname = blog1 httpport = runmode = dev controllersmy package controllersmy //跟外面的包名一致 imp ...

  4. Codeforces Round #311 (Div. 2) D - Vitaly and Cycle

    D. Vitaly and Cycle time limit per test 1 second memory limit per test 256 megabytes input standard ...

  5. SICP习题练习

    练习1.6 new-if的三个参数会先被执行,这样就会无限循环下去 练习1.7 (define (sqrt-iter last-guess guess x) (if (good-enough? las ...

  6. 使用SwingWork反而阻塞SwingUI

    最近加载图片的过程中使用了SwingWork来下载图片,但是发现会使得Swing的UI界面假死 查看了一下资料,SwingWork的设计初衷就是为了解决卡死UI的问题,正常使用应该没有问题,但是有一点 ...

  7. E20170527-ts

    asset   n. 资产,财产; 有价值的人或物; 有用的东西; 优点; serializer  [词典] 串行(化)器(把并行数据变成串行数据的寄存器); 编程语言中,可被序列化的; inflec ...

  8. vue商品详情页添加动画(eg)

    <template> <div class="food" transition="move"></div> </tem ...

  9. 矩阵取数游戏 2007年NOIP全国联赛提高组(dp+高精)

    矩阵取数游戏 2007年NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold     题目描述 Description [问题描述]帅帅经常跟 ...

  10. 洛谷P3371 【模板】单源最短路径(弱化版)(SPFA解法)

    题目背景 本题测试数据为随机数据,在考试中可能会出现构造数据让SPFA不通过,如有需要请移步 P4779. 题目描述 如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度. 输入输出格式 输 ...