1.Promise思想:每一个异步任务立刻返回一个Promise对象,由于是立刻返回,所以可以采用同步操作的流程。这个Promises对象有一个then方法,允许指定回调函数,在异步任务完成后调用。

  1. // 传统写法
  2. step1(function (value1) {
  3. step2(value1, function(value2) {
  4. step3(value2, function(value3) {
  5. step4(value3, function(value4) {
  6. // ...
  7. });
  8. });
  9. });
  10. });
  11.  
  12. // Promises的写法
  13. (new Promise(step1))
  14. .then(step2)
  15. .then(step3)
  16. .then(step4);

传统的回调函数写法使得代码混成一团,变得横向发展而不是向下发展。Promises规范就是为了解决这个问题而提出的,目标是使用正常的程序流程(同步),来处理异步操作。它先返回一个Promise对象,后面的操作以同步的方式,寄存在这个对象上面。等到异步操作有了结果,再执行前期寄放在它上面的其他操作。

ECMAScript 6将其写入语言标准,因此目前JavaScript语言原生支持Promise对象。

2.Promise接口

  接口状态

(1)未完成 pending

(2)完成 resolved或者fulfilled

(3)失败 rejected

  状态变化途径

(1)未完成-完成

(2)未完成-失败

  Promise对象最终结果

(1)异步操作成功,Promise对象传回一个值,状态变为resolved

(2)异步操作失败,Promise对象抛出错误,状态变为rejected

  then方法

Promise对象使用then方法添加回调函数,then方法可以接受两个回调函数,一个是异步操作成功(状态为resolved)时的回调函数,一个是异步操作失败(状态为rejected)时的回调函数。

then方法可以链式调用:

  1. po
  2. .then(step1)
  3. .then(step2)
  4. .then(step3)
  5. .then(
  6. console.log,
  7. console.error
  8. );

上面代码中,po的状态一旦变为resolved,就依次调用后面每一个then指定的回调函数,每一步都必须等到前一步完成,才会执行。最后一个then方法的回调函数console.logconsole.error,用法上有一点重要的区别。console.log只显示回调函数step3的返回值,而console.error可以显示step1step2step3之中任意一个发生的错误。也就是说,假定step1操作失败,抛出一个错误,这时step2step3都不会再执行了(因为它们是操作成功的回调函数,而不是操作失败的回调函数)。Promises对象开始寻找,接下来第一个操作失败时的回调函数,在上面代码中是console.error。这就是说,Promises对象的错误有传递性

3.Promise对象的生成

ES6提供了原生的Promise构造函数,用来生成Promise实例。

  1. var promise = new Promise(function(resolve, reject){
  2. //异步操作的代码
  3. if(/*异步操作成功*/){
  4. resolve(value);
  5. }else{
  6. reject(error);
  7. }
  8. })

resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从Pending变为Resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从Pending变为Rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

4.Promise用法辨析

(1)finalHandler回调函数的参数是doSomethingElse函数的运行结果

  1. doSomething().then(function () {
  2. return doSomethingElse();
  3. }).then(finalHandler);

(2)finalHandler回调函数的参数是undefined

  1. doSomething().then(function () {
  2. doSomethingElse();
  3. return;
  4. }).then(finalHandler);

(3)finalHandler回调函数的参数,是doSomethingElse函数返回的回调函数的运行结果

  1. doSomething().then(doSomethingElse())
  2. .then(finalHandler);

(4)doSomethingElse会接收到doSomething()返回的结果

  1. doSomething().then(doSomethingElse)
  2. .then(finalHandler);

5.Promise优缺点

优点:让回调函数变成了规范的链式写法,程序流程可以看得很清楚。如果一个任务已经完成,再添加回调函数,该回调函数会立即执行。所以,你不用担心是否错过了某个事件或信号。

缺点:编写和理解都相对比较难。

如有错误,请您指正!

参考文档:

Promise

Promise对象的更多相关文章

  1. angular学习笔记(二十八-附2)-$http,$resource中的promise对象

    下面这种promise的用法,我从第一篇$http笔记到$resource笔记中,一直都有用到: HttpREST.factory('cardResource',function($resource) ...

  2. ES6深入学习记录(二)promise对象相关

    1.Promise的含义 Promise是异步编程的一种解决方案,比传统的解决方案--回调函数和事件更合理和强大.ES6将其写进了语言标准,统一了用法,原生提供了promise对象. 所谓Promis ...

  3. es6中的promise对象

    Promise是异步里面的一种解决方案,解决了回调嵌套的问题,es6将其进行了语言标准,同意了用法,提供了`promise`对象, promise对象有三种状态:pending(进行中) .Resol ...

  4. ES6的promise对象应该这样用

    ES6修补了一位Js修真者诸多的遗憾. 曾几何时,我这个小白从js非阻塞特性的坑中爬出来,当我经历了一些回调丑陋的写法和优化的尝试之后,我深深觉得js对于多线程阻塞式的开发语言而言,可能有着其太明显的 ...

  5. Angularjs promise对象解析

    1.先来看一段Demo,看完这个demo你可以思考下如果使用$.ajax如何处理同样的逻辑,使用ng的promise有何优势? var ngApp=angular.module('ngApp',[]) ...

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

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

  7. angularJS中的Promise对象($q)的深入理解

    原文链接:a better way to learn AngularJS - promises AngularJS通过内置的$q服务提供Promise编程模式.通过将异步函数注册到promise对象, ...

  8. 通过一道笔试题浅谈javascript中的promise对象

    因为前几天做了一个promise对象捕获错误的面试题目,所以这几天又重温了一下promise对象.现在借这道题来分享下一些很基础的知识点. 下面是一个面试题目,三个promise对象捕获错误的例子,返 ...

  9. ECMAScript6的Promise对象

    1. 概念 Promise对象用于异步(asynchronouss)计算,一个Promise对象代表着一个还未完成,但预期完成的操作. 2. 出现原因: 1)  如果你需要通过ajax发送多次请求,而 ...

随机推荐

  1. LeetCode Find All Anagrams in a String

    原题链接在这里:https://leetcode.com/problems/find-all-anagrams-in-a-string/ 题目: Given a string s and a non- ...

  2. CentOS下使用Postfix + Dovecot + Dnsmasq搭建极简局域网邮件系统

    背景 开发环境为局域网,工作内容需要经常查看邮件文件(*.eml),可恶的Foxmail必须验证账户才能进入主界面,才能打开eml文件查看. 无奈搭一个局域网内的邮件系统吧.极简搭建,仅用于通过Fox ...

  3. 使用JCIFS获取远程共享文件

    package com.jadyer.util;  import java.io.File; import java.io.FileOutputStream; import java.io.IOExc ...

  4. SQL,根据不同条件拼接不同SQL,非if拼接 改为SQL where形式

    (参数) and 其他条件)

  5. GPS部标平台的架构设计(十)-基于Asp.NET MVC构建GPS部标平台

    在当前很多的GPS平台当中,有很多是基于asp.NET+siverlight开发的遗留项目,代码混乱而又难以维护,各种耦合和关联,要命的是界面也没见到比Javascript做的控件有多好看,随着需求的 ...

  6. 利用Python实现从百度下载图片到本地磁盘

    import urllib.request import os import re url=r'http://image.baidu.com/search/index?tn=baiduimage&am ...

  7. 多线程中共享变量——CCF总决赛试题

    题目要求 数据格式 Q 系统的输入为纯文本格式的文件,由若干行组成,每一行由城市编号.年龄.收入组成,相邻两项之间用一个空格分隔.以下是输入的一个片段: 1001 20 12000 1001 50 2 ...

  8. activity 所需jiar包

    activity下载后有很多jar包有的jar包不一定用得上,也有些jar是重复的,这里就整理了一下必要的jar包 路径.. \activiti-5.19.0.2\wars\activiti-expl ...

  9. Server.MapPath和Request.PhysicalApplicationPath的异同

    很多人对它们都不陌生,在众多的WEB程序中,使用Server.MapPath和Request.PhysicalApplicationPath来操作目录/文件的几率参半,我曾经也经常混用,然而时间久了. ...

  10. Windows下底层数据包发送实战

    1.简介 所谓“底层数据包”指的是在“运行”于数据链路层的数据包,简单的说就是“以太网帧”,而我们常用的Socket只能发送“运行”在传输层的TCP.UDP等包,这些传输层数据包已经能满足绝大部分需求 ...