在说Promise之前我们先简单说一下什么是同步异步?

   同步(Sync):所谓同步,就是发出一个功能调用时,在没有得到结果之前,该调用就不返回或继续执行后续操作。

   异步(Async):异步与同步相对,当一个异步过程调用发出后,调用者在没有得到结果之前,就可以继续执行后续操作。当这个调用完成后,一般通过状态、通知和回调来通知调用者。

Promise是什么?

  Promise是JS异步编程中的重要概念,异步抽象处理对象,是目前比较流行Javascript异步编程解决方案之一。这句话说的很明白了,Promise是一种用于解决异步问题的思路、方案或者对象方式。

  在js中,经常使用异步的地方是Ajax交互。比如在es5时代,jQuery的ajax的使用success来完成异步的:

$.ajax({
url:'/xxx',
success:()=>{},
error: ()=>{}
})

  这种方法可以清楚的让读代码的人明白那一部分是Ajax请求成功的回调函数和失败的回调函数。但是问题来了,当一次请求需要连续请求多个接口时,这段代码仿佛进入了一团乱麻中:

// 第一次
$.ajax({
url:'/xxx',
success:()=>{
// 第二次
$.ajax({
url:'/xxx',
success:()=>{
// 第三次
$.ajax({
url:'/xxx',
success:()=>{
// 可能还会有
},
error: ()=>{}
})
},
error: ()=>{}
})
},
error: ()=>{}
})

  也许因为success和error这两个函数的存在,理解这段代码会很简单,但是当我们更改需求的时候,这将成为一个棘手的问题。这就是回调地狱。

  当然,这是es5时代。当js这门语言发展到es6时代时,Promise的出现给异步带来了变革。Promise提供一个then,来为异步提供回调函数:

$.ajax({
url:'/xxx',
}).then( ()=>{
// 成功的回调
}, ()=>{
// 失败的回调
})

  而其先进之处则是,可以在then方法中继续写Promise对象并返回,然后继续调用then来进行回调操作。

Promise的特点?

  • 对象的状态不会受到外界的影响。Promise代表的是一个异步的操作。一共有三种状态pending(进行中),resolved(已做完)和rejected(已失败),异步操作的结果,决定这Promise最终的状态。成功的则会使用resolved作为回调,如果失败则会使用rejected作为回调,任何的操作都无法改变其中的状态。
  • Promise的状态一旦改变,就永远不会再改变。Promise的改变只有两种情况,Pending –> rejected或者Pending-> resolved,Promise的最大特点也就是在此,如果你错过了他的返回结果,如果再想通过某种方法,去获得Promise的返回结果是获取不到的。

简单来说,Promise 就是用同步的方式写异步的代码,用来解决回调问题

then()方法

  then 方法就是把原来的回调写法分离出来,在异步操作执行完后,用链式调用的方式执行回调函数。

  而 Promise 的优势就在于这个链式调用。我们可以在 then 方法中继续写 Promise 对象并返回,然后继续调用 then 来进行回调操作。

  下面做一个吃早饭的演示,它们是层层依赖的关系,下一步的的操作需要使用上一部操作的结果。(这里使用 setTimeout 模拟异步操作),正式开发可以用 ajax 异步

    function cake() {
console.log('排队买早饭')
let breakfast = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('买了手抓饼')
resolve('手抓饼')
}, 100)
})
return breakfast
} function eat(data) {
console.log('开始吃早饭:' + data)
let eatbreakfast = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('吃完早饭')
resolve('去上班')
}, 100)
});
return eatbreakfast
}
cake().then((res) => {
return eat(res)
}).then((res) => {
console.log(res)
})

  打印结果:

  

catch()方法:

  catch在链式写法中可以捕获前面then中发送的异常。

    function cake() {
console.log('排队买早饭')
let breakfast = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('没买到饼')
reject('饼买光了')
}, 100)
})
return breakfast
} function eat(data) {
console.log('开始吃早饭:' + data)
let eatbreakfast = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('吃完早饭')
resolve('去上班')
}, 100)
});
return eatbreakfast
}
cake().then((res) => {
return eat(res)
}).catch((res) => {
console.log(res)
})

打印结果:

  

  它的另一个作用是,当执行 resolve 的回调(也就是上面 then 中的第一个参数)时,如果抛出异常了(代码出错了),那么也不会报错卡死 js,而是会进到这个 catch 方法中。

    function cake() {
console.log('排队买早饭')
let breakfast = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('买了豆浆')
resolve('豆浆')
}, 100)
})
return breakfast
} function eat(data) {
console.log('开始吃早饭:' + data)
let eatbreakfast = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('吃完早饭')
resolve('去上班')
}, 100)
});
return eatbreakfast
}
cake().then((res) => {
throw new Error("买了坏的豆浆");
return eat(res)
}).catch((res) => {
console.log(res)
})

打印结果:

  

all()方法:

  Promise 的 all 方法提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行回调。

  比如下面代码,两个个异步操作是并行执行的,等到它们都执行完后才会进到 then 里面。同时 all 会把所有异步操作的结果放进一个数组中传给 then。

    function eat() {
console.log('排队买手抓饼')
let breakfast = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('刚做好的手抓饼')
resolve('热乎的手抓饼')
}, 100)
})
return breakfast
} function drink() {
console.log('排队买豆浆')
let soybean = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('刚打磨的豆浆')
resolve('热乎的豆浆')
}, 100)
})
return soybean
}
Promise.all([eat(), drink()]).then((results) =>{
console.log("早饭都买好了")
console.log(results)
})

  

打印结果:

  

race()方法:

  race 按字面解释,就是赛跑的意思。race 的用法与 all 一样,只不过 all 是等所有异步操作都执行完毕后才执行 then 回调。而 race 的话只要有一个异步操作执行完毕,就立刻执行 then 回调。

  注意:其它没有执行完毕的异步操作仍然会继续执行,而不是停止。

  这里我们将上面样例的 all 改成 race

    function eat() {
console.log('排队买手抓饼')
let breakfast = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('刚做好的手抓饼')
resolve('热乎的手抓饼')
}, 100)
})
return breakfast
} function drink() {
console.log('排队买豆浆')
let soybean = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('刚打磨的豆浆')
resolve('热乎的豆浆')
}, 100)
})
return soybean
}
Promise.race([eat(), drink()]).then((results) =>{
console.log("哈哈,早饭都买好了")
console.log(results)
})

  打印结果:

  

ES6 中 Promise的更多相关文章

  1. 对于ES6中Promise的个人见解

    1.js中常见的异步 JavaScript可以响应用户的一些异步交互,比如单击鼠标和按键盘等操作. let button = document.getElementById("btn&quo ...

  2. ES6中Promise对象个人理解

    Promise是ES6原生提供的一个用来传递异步消息的对象.它减少了传统ajax金字塔回调,可以将异步操作以同步操作的流程表达出来使得代码维护和可读性方面好很多. Promise的状态: 既然是用来传 ...

  3. ES6中promise的使用方法

    先看看ES5中异步编程的使用. let ajax = function (callBlack) { setTimeout(function () { callBlack && call ...

  4. ES6中promise总结

    一.什么是ES6的Promise 讲太多也没有.直接在打印出来就好,console.dir(Promise) Promise 是一个构造函数,自身有all, reject, resolve 这几个眼熟 ...

  5. ES6中Promise的入门(结合例子)

    一.Promise的前言 解决回调地狱 //以往回调方式 函数1(function(){ //代码执行...(ajax1) 函数2(function(){ //代码执行...(ajax2) 函数3(f ...

  6. ES6 中 Promise 详解

    Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果.从语法上说,Promise 是一个对象,从它可以获取异步操作的消息.Promise 提供统一的 API ...

  7. ES6中Promise详解

    Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果.从语法上说,Promise 是一个对象,从它可以获取异步操作的消息. Promise 提供统一的 AP ...

  8. 阿里前端测试题--关于ES6中Promise函数的理解与应用

    今天做了阿里前端的笔试题目,原题目是这样的 //实现mergePromise函数,把传进去的数组顺序先后执行,//并且把返回的数据先后放到数组data中 const timeout = ms => ...

  9. 关于ES6中Promise的应用-顺序合并Promise,并将返回结果以数组的形式输出

    1.Promise 基础知识梳理 创建一个Promise实例 const promise = new Promise(function(resolve, reject) { if (success){ ...

随机推荐

  1. [C++ Primer Plus] 第8章、函数探幽(一)程序清单——内联、引用、格式化输入输出、模板、decltype

    程序清单8.1(inline内联函数) #include<iostream> using namespace std; inline double square(double x) {// ...

  2. 2019.04.16打卡(java 数组)

    1.  要求输出数组中数据的平均值,并输出所有大于平均值的数据 代码 package block; import java.util.*; public class Average { public ...

  3. scrapy 爬虫的暂停与重启

    暂停爬虫项目 首先在项目目录下创建一个文件夹用来存放暂停爬虫时的待处理请求url以及其他的信息.(文件夹名称:job_info) 在启动爬虫项目时候用pycharm自带的终端启动输入下面的命令: sc ...

  4. 牛客练习赛43F Tachibana Kanade Loves Game

    题目地址 Link 题解 这题其实就是求1~n中有多少与2~20互质的数,然后其实只跟1~20里面的质数有关. 那么考虑容斥一下求出来一共有多少个不互质的,用n减一下就是互质的数的个数了.然后判一下a ...

  5. 如何在Windows上的Jupyter Notebook中安装和运行PySpark

    When I write PySpark code, I use Jupyter notebook to test my code before submitting a job on the clu ...

  6. 1、docker容器技术基础入门

    Docker和传统虚拟机的区别               参考文章: https://lwn.net/Articles/531114/    操作中的命名空间详解 https://blog.yadu ...

  7. 访问github慢的解决方案

    问题描述 打开https://github.com很慢. 解决办法 1.打开文件C:\Windows\System32\drivers\etc\hosts 2.添加如下内容: 151.101.44.2 ...

  8. C语言 Struct 结构体在 Java 中的体现

    大一整个学期完成了 C 语言的学习,大二就进入了Java 的学习. 和C语言一样,我们都会尝试写一个小小的学生管理系统什么的,学习过 C 语言同学知道,在管理系统中 Struct 结构体是个很好用的东 ...

  9. Rancher2.0与DataDog集成部署

    目录 一.简要介绍 二.注意事项 三.部署过程 四.运行截图 五.参考链接 一.简要介绍: 看了Rancher中文官网上的一篇关于DataDog部署的文章,自己尝试了一下,没有成功,主要是自己对Dat ...

  10. Ubuntu 16.04安装httpd

    1.下载httpd源码(当前版本为2.4.37) http://httpd.apache.org/download.cgi 2.解压编译 tar -zxf httpd-2.4.37.tar.gzcd ...