异步编程——promise

定义

Promise是异步编程的一个解决方案,相比传统的解决方法——回调函数,使用Promise更为合理和强大,避免了回调函数之间的层层嵌套,也使得代码结构更为清晰,便于维护。Promise 是一个对象,从他可以获取异步操作的消息,他也是一个容器,里面包含着事件结束之后要进行的操作。

特点

Promise对象有两个特点:

  • 对象的状态不收外界干扰。Promise对象有三种状态:pending(进行中)、resolved(已完成)、rejected(已失败),具体处于哪一种状态是由异步操作的结果来决定的,其他的任何操作都无法改变这个状态。
  • 一旦状态改变了,就不会再有其他的改变了,任何时候都能得到这个结果。Promise对象状态的改变有两种:1>.pending状态到resolved状态;2>.pending状态到rejected状态;

用法

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

  1. var promise = new Promise(function(resolve,reject){
  2. if(/异步成功/){
  3. resolve(val);
  4. }else{
  5. reject(val);
  6. }
  7. });
  8. promise.then(function(val){
  9. /成功后执行的函数/
  10. },function(error){
  11. /失败后执行的函数/
  12. });

Promise构造函数接收一个函数作为参数,这个函数有两个参数resolve、reject,这两个参数也是两个函数,有javascript引擎提供,不需要自己实现。其中,resolve函数的作用是将Promise对象的状态由"进行中"变为"已完成",在异步操作成功的时候调用,并将异步操作的结果以参数的形式传出,就是上例中的val。reject函数的作用是将Promise对象的状态由"进行中"变为"已失败",在异步操作失败的时候调用,并将操作失败的错误已参数的形式传出。

Promise的实例可以调用then方法,then方法有两个函数作为参数,第一个函数是Promise对象状态变为resoloved时执行的函数,第二个函数是Promise对象状态变为rejected时执行的函数,第二个参数是可选的。

一个典型的例子:异步读取文件

  1. function readFileFn(filename){
  2. return new Promise(function(resolve,reject){
  3. fs.readfile(filename,function(err,data){
  4. if(err){
  5. reject(err);
  6. }else{
  7. resolve(data);
  8. }
  9. });
  10. });
  11. }
  12. readFileFn("./test.txt").then(function(data){
  13. console.log(data.toString());
  14. //其他操作...
  15. },function(err){
  16. console.log(err);
  17. });

then方法可以采用链式的写法,即:

promise.then(...).then(...).then(..)

具体的例子:

  1. var promise = new Promse(function(resolve,reject){
  2. resolve(1);    //将Promise对象的状态改为resolved,并传递参数1
  3. });
  4. promise.then(function(val){
  5. console.log(val);  // 1
  6. return val*3;
  7. }).then(function(val){
  8. console.log(val);  //3
  9. return val*3;
  10. }).then(function(val){
  11. console.log(val);  //9
  12. });

Promise对象的一些其他方法

  • Promise.prototype.catch:用于指定发生错误时的回调函数,通常的用法是在then方法里省略第二个参数,然后在链式调用的尾部使用catch方法来捕获异步操作或者then方法中的错误;
  1. readFileFn("./test.txt").then(function(data){
  2. console.log(data.toString());
  3. //其他操作...
  4. }).catch(function(err){
  5. console.log(err);
  6. })
  7. //另一种用法
  8. var promise = new Promise(function(resolve,reject){
  9. reject(new Error("test"));
  10. });
  11. promise.then(function(val){
  12. //...
  13. }).catch(function(err){
  14. console.log(err);
  15. //..
  16. });
  • Promise.all():次方法用于将多个Promise实例包装成一个新的Promise实例。Promise.all()方法接收一个数组作为参数:

var p = Promise.all([a,b,c]);  //a,b,c都是Promise的实例

p最终的状态由a,b,c三者决定:

1>.当a,b,c的状态都是resolved时,p的状态才是resolved,此时a,b,c的返回值组成一个数组,传给p的回调函数。

2>.只要 a,b,c中有一个状态时reject,p的状态就是reject,此时一个reject的实例的返回值会传递给p的回调函数。

  1. var promises = [1,2,3,4].map(function(id){
  2. return readFileFn("./test"+id+".txt");  //readFileFn()是上面声明过的函数
  3. });
  4. Promise.all(promises).then(function(val){
  5. //...
  6. }).catch(function(err){
  7. //...
  8. });
  • Promise.race():同样是将多个Promise实例包装成一个新的Promise实例,与Promise.all()方法类似;
  • Promise.resolve():将一个非Promise对象转换为一个Promise对象,

var promise = Promise.resolve($.ajax("./test.txt"));

Promise.resolve()有四种类型的参数:

1>.Promise实例,那么函数不会对参数做任何修改,原样返回;

2>.普通对象,如同上例,会转换成一个promise对象返回;

3>.非对象,即普通的变量,比如"hello"、2 等等,此时会返回一个新的Promise实例,状态为resolved(),"hello"会以参数的形式传给then的第一个方法;

  1. var p = Promise.resolve("hello");
  2. p.then(function(val){        //此函数会立即执行
  3. console.log(val);  //hello
  4. });

4>.不带参数,会直接返回一个Resolved状态的Promise对象。

  • Promise.reject():返回一个状态为rejected的实例,参数类似于Promise.resolve()方法的第三种参数。
  • done():Promise内部的错误不会冒泡到全局,所以,如果回调链的最后一个出现错误,就无法被捕获,所以有了done()方法,位于回调链的最尾端,用于捕获错误。

promise.then(function(){}).then(function(){}).catch(function(){}).done();

  • finally():指定不管Promise最后的状态如何都会执行的操作,他与done()的区别是可以接受一个普通的回调函数作为参数,且该函数一定会执行。

异步编程——promise的更多相关文章

  1. 简单实现异步编程promise模式

    本篇文章主要介绍了异步编程promise模式的简单实现,并对每一步进行了分析,需要的朋友可以参考下 异步编程 javascript异步编程, web2.0时代比较热门的编程方式,我们平时码的时候也或多 ...

  2. 异步编程Promise/Deferred、多线程WebWorker

    长期以来JS都是以单线程的模式运行的,而JS又通常应用在操作用户界面和网络请求这些任务上.操作用户界面时不能进行耗时较长的操作否则会导致界面卡死,而网络请求和动画等就是耗时较长的操作.所以在JS中经常 ...

  3. 简述异步编程&Promise&异步函数

    前言:文章由本人在学习之余总结巩固思路,不足之前还请指出. 一.异步编程 首先我们先简单来回顾一下同步API和异步API的概念 1.同步API:只有当前的API执行完成之前,才会执行下一个API 例: ...

  4. 异步编程promise

    异步编程发展 异步编程经历了 callback.promise.async/await.generator四个阶段,其中promise和async/await使用最为频繁,而generator因为语法 ...

  5. AnjularJS异步编程 Promise和$q

    Promise,是一种异步处理模式. js代码的函数嵌套会使得程序执行异步代码时很难调试.因为多重嵌套的函数无法确定何时触发回调. 如: funA(arg1,arg2,function(){ func ...

  6. es6异步编程 Promise 讲解 --------各个优点缺点总结

    //引入模块 let fs=require('fs'); //异步读文件方法,但是同步执行 function read(url) { //new Promise 需要传入一个executor 执行器 ...

  7. 你所必须掌握的三种异步编程方法callbacks,listeners,promise

    目录: 前言 Callbacks Listeners Promise 前言 coder都知道,javascript语言运行环境是单线程的,这意味着任何两行代码都不能同时运行.多任务同时进行时,实质上形 ...

  8. JavaScript异步编程 ( 一 )

    1. 异步编程 Javascript语言的执行环境是"单线程"(single thread).所谓"单线程",就是指一次只能完成一件任务.如果有多个任务,就必须 ...

  9. JavaScript异步编程(1)- ECMAScript 6的Promise对象

    JavaScript的Callback机制深入人心.而ECMAScript的世界同样充斥的各种异步操作(异步IO.setTimeout等).异步和Callback的搭载很容易就衍生"回调金字 ...

随机推荐

  1. 网络编程3 网络编程之缓冲区&subprocess&粘包&粘包解决方案

    1.sub简单使用 2.粘包现象(1) 3.粘包现象(2) 4.粘包现象解决方案 5.struct学习 6.粘包现象升级版解决方案 7.打印进度条

  2. Oracle实例的恢复、介质恢复( crash recovery)( Media recovery)

    实例的恢复( crash recovery) 什么时候发生Oracle实例恢复? shutdown abort; 数据库异常down掉(机器死机,掉电...) 实例恢复的原因是数据有丢掉,使用redo ...

  3. 【Python之路】第十七篇--Ajax全套

    概述 1.传统的Web应用 一个简单操作需要重新加载全局数据 2.AJAX AJAX,Asynchronous JavaScript and XML (异步的JavaScript和XML),一种创建交 ...

  4. 开机启动/etc/rc.local失效无效怎么办?解决方法

    开机启动/etc/rc.local失效问题的解决方法 第一种情况:当centOS 随机启动文件 /etc/rc.local 失效时请按如下修改1.echo /etc/rc.local >> ...

  5. Java集合类学习记录

    被标记为transient的属性在对象被序列化的时候不会被保存int[] arr1 = {1, 2, 3, 4, 5}; int[] arr2 = Arrays.copyOf(arr1, new_le ...

  6. node.js基本工作原理及流程

    概述 Node.js是什么 Node 是一个服务器端 JavaScript 解释器,用于方便地搭建响应速度快.易于扩展的网络应用.Node.js 使用事件驱动, 非阻塞I/O 模型而得以轻量和高效,非 ...

  7. Spring 数据库连接池读取系统环境变量作为参数

    原来是写在一个properties文件里面,后来项目要部署的的确太多了,每次更改不太方便,就想把这些固定不变的信息写在当地的环境变量里面 原先是这样的:引用的所有信息在jdbc.properties ...

  8. ansible安装及使用

    一.ansible介绍 1.ansible简介 官方的title是“Ansible is Simple IT Automation”——简单的自动化IT工具. Ansible跟其他IT自动化技术的区别 ...

  9. 在用 JavaScript 工作时,我们经常和条件语句打交道,这里有5条让你写出更好/干净的条件语句的建议。

    1.多重判断时使用 Array.includes 2.更少的嵌套,尽早 return 3.使用默认参数和解构 4.倾向于遍历对象而不是 Switch 语句 5.对 所有/部分 判断使用 Array.e ...

  10. insert获取主键、联合关联查询

    联合查询