一、Promise的含义

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

1、Promise对象两大特点

1.对象的状态不受外界影响
  • Promise对象代表一个异步操作,有三种状态:Pending(进行中)、Resolved(已完成,又称Fulfilled)和Rejected(已失败)。
  • 只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
2.一旦状态改变,就不会再变,任何时候都可以得到这个结果。
  • Promise对象的状态改变,只有两种可能:从Pending变为Resolved和从Pending变为Rejected。

二、基本用法

1、ES6规定,Promise对象是一个构造函数,用来生成Promise实例

var promise = new Promise(function(resolve, reject) {
// ... some code if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
  • Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由JavaScript引擎提供,不用自己部署。

  • resolve函数的作用是,将Promise对象的状态从‘未完成’变成‘成功’(即Pending变成Resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去

  • reject函数的作用是,将Promise对象的状态从‘未完成’变为‘失败’(即从Pending变成Rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去

  • Promise实例生成后,可以用then方法分别制定Resolved状态和Reject状态的回调函数

      promise.then(function(value) {
    // success
    }, function(error) {
    // failure
    });
  • then方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为Resolved时调用,第二个回调函数是Promise对象的状态变为Reject时调用。其中,第二个函数是可选的,不一定要提供。这两个函数都接受Promise对象传出的值作为参数。

      function timeout(ms) {
    return new Promise((resolve, reject) => {
    setTimeout(resolve, ms, 'done');
    });
    } timeout(100).then((value) => {
    console.log(value);
    });

三、Promise.prototype.then()

  • Promise实例具有then方法,也就是说,then方法是定义在原型对象Promise.prototype上的。它的作用是为Promise实例添加状态改变时的回调函数。

四、Promise.prototype.catch()

  • Promise.prototype.catch方法是.then(null, rejection)的别名,用于指定发生错误时的回调函数。

五、Promise.all()

  • Promise.all方法用于将多个Promise实例,包装成一个新的Promise实例。

      var p = Promise.all([p1, p2, p3]);

六、Promise.race()

  • Promise.race方法同样是将多个Promise实例,包装成一个新的Promise实例。

      var p = Promise.race([p1,p2,p3]);

七、Promise.resolve()

  • 有时需要将现有对象转为Promise对象,Promise.resolve方法就起到这个作用。

      var jsPromise = Promise.resolve($.ajax('/whatever.json'));
  • Promise.resolve等价于下面的写法。

      Promise.resolve('foo')
    // 等价于
    new Promise(resolve => resolve('foo'))

Promise.resolve方法的参数分成四种情况。

(1)参数是一个Promise实例
  • 如果参数是Promise实例,那么Promise.resolve将不做任何修改、原封不动地返回这个实例。
(2)参数是一个thenable对象
  • thenable对象指的是具有then方法的对象,比如下面这个对象。

      let thenable = {
    then: function(resolve, reject) {
    resolve(42);
    }
    };
  • Promise.resolve方法会将这个对象转为Promise对象,然后就立即执行thenable对象的then方法。

      let thenable = {
    then: function(resolve, reject) {
    resolve(42);
    }
    }; let p1 = Promise.resolve(thenable);
    p1.then(function(value) {
    console.log(value); // 42
    });
  • 上面代码中,thenable对象的then方法执行后,对象p1的状态就变为resolved,从而立即执行最后那个then方法指定的回调函数,输出42。

(3)参数不是具有then方法的对象,或根本就不是对象
  • 如果参数是一个原始值,或者是一个不具有then方法的对象,则Promise.resolve方法返回一个新的Promise对象,状态为Resolved。

      var p = Promise.resolve('Hello');
    
      p.then(function (s){
    console.log(s)
    });
    // Hello
  • 上面代码生成一个新的Promise对象的实例p。由于字符串Hello不属于异步操作(判断方法是它不是具有then方法的对象),返回Promise实例的状态从一生成就是Resolved,所以回调函数会立即执行。Promise.resolve方法的参数,会同时传给回调函数。

(4)不带有任何参数
  • Promise.resolve方法允许调用时不带参数,直接返回一个Resolved状态的Promise对象。

八、Promise.reject()

  • Promise.reject(reason)方法也会返回一个新的Promise实例,该实例的状态为rejected。它的参数用法与Promise.resolve方法完全一致。

      var p = Promise.reject('出错了');
    // 等同于
    var p = new Promise((resolve, reject) => reject('出错了')) p.then(null, function (s){
    console.log(s)
    });
    // 出错了

九、两个有用的附加方法

1.done()

  • Promise对象的回调链,不管以then方法或catch方法结尾,要是最后一个方法抛出错误,都有可能无法捕捉到(因为Promise内部的错误不会冒泡到全局)。因此,我们可以提供一个done方法,总是处于回调链的尾端,保证抛出任何可能出现的错误。

      asyncFunc()
    .then(f1)
    .catch(r1)
    .then(f2)
    .done();
  • 它的实现代码相当简单。

      Promise.prototype.done = function (onFulfilled, onRejected) {
    this.then(onFulfilled, onRejected)
    .catch(function (reason) {
    // 抛出一个全局错误
    setTimeout(() => { throw reason }, 0);
    });
    };

2.finally()

  • finally方法用于指定不管Promise对象最后状态如何,都会执行的操作。它与done方法的最大区别,它接受一个普通的回调函数作为参数,该函数不管怎样都必须执行。

  • 服务器使用Promise处理请求,然后使用finally方法关掉服务器。

      server.listen(0)
    .then(function () {
    // run test
    })
    .finally(server.stop);
  • 它的实现也很简单。

      Promise.prototype.finally = function (callback) {
    let P = this.constructor;
    return this.then(
    value => P.resolve(callback()).then(() => value),
    reason => P.resolve(callback()).then(() => { throw reason })
    );
    };

十、应用

1、加载图片

  • 我们可以将图片的加载写成一个Promise,一旦加载完成,Promise的状态就发生变化。

      const preloadImage = function (path) {
    return new Promise(function (resolve, reject) {
    var image = new Image();
    image.onload = resolve;
    image.onerror = reject;
    image.src = path;
    });
    };

2、Generator函数与Promise的结合

  • 使用Generator函数管理流程,遇到异步操作的时候,通常返回一个Promise对象。

      function getFoo () {
    return new Promise(function (resolve, reject){
    resolve('foo');
    });
    } var g = function* () {
    try {
    var foo = yield getFoo();
    console.log(foo);
    } catch (e) {
    console.log(e);
    }
    }; function run (generator) {
    var it = generator(); function go(result) {
    if (result.done) return result.value; return result.value.then(function (value) {
    return go(it.next(value));
    }, function (error) {
    return go(it.throw(error));
    });
    } go(it.next());
    } run(g);
  • 面代码的Generator函数g之中,有一个异步操作getFoo,它返回的就是一个Promise对象。函数run用来处理这个Promise对象,并调用下一个next方法。

简单例子

    let state = 1;
function step1(resolve,reject){
console.log('1-开始洗菜做饭');
if( state == 1){
resolve('洗菜做饭完成');
}else {
reject('洗菜做饭出错');
}
} function step2(resolve,reject){
console.log('2-开始-坐下来吃饭');
if (state == 1) {
resolve('坐下来吃饭完成');
}else {
reject('坐下来吃饭出错');
}
} function step3(resolve,reject) {
console.log('3-开始收拾桌子洗碗');
if(state==1){
resolve('收拾桌子洗碗完成');
}else{
reject('收拾桌子洗碗出错')
}
} new Promise(step1).then(function(val){
console.log(val);
return new Promise(step2);
}).then(function(val){
console.log(val);
return new Promise(step3);
}).then(function(val){
console.log(val);
return val;
})

ECMAScript 6 Promise 对象的更多相关文章

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

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

  2. Promise对象

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

  3. JavaScript 初识Promise 对象

    什么是Promise? 其实, Promise就是一个类,而且这个类已经成为ES6的标准,是 ECMAScript 6 规范的重要特性之一.这个类目前在chrome32.Opera19.Firefox ...

  4. ES6 之 let和const命令 Symbol Promise对象

    ECMAScript 6入门 ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准,已经在2015年6月正式发布了. (2016年6月,发布了小幅修订的<ECMASc ...

  5. 前端基本知识(四):JS的异步模式:1、回调函数;2、事件监听;3、观察者模式;4、promise对象

    JavaScript语言将任务的执行模式可以分成两种:同步(Synchronous)和异步(Asychronous). “同步模式”就是一个任务完成之后,后边跟着一个任务接着执行:程序的执行顺序和排列 ...

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

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

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

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

  8. es6中的promise对象

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

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

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

随机推荐

  1. git 恢复单个文件

    首先查看该文件的历史版本信息:git log Default@2x.png 记录下需要恢复的commit版本号:如 9aa51d89799716aa68cff3f30c26f8815408e926 恢 ...

  2. Jmeter远程启动负载机

    1.负载机下载Jmeter,设置环境变量,jmeter中进行启动jmeter-server的应用服务.环境变量设置如下: 变量名:JMETER_HOME 变量值:C:\Program Files\ap ...

  3. 【JavaScript】JAVA-input如何占满整个td

    如果使用下面这种方式,不会出现占满效果 <tr> <td colspan="2"> <input width="90%" alig ...

  4. 520的信心赛——点点玩deeeep

                                   3.点点玩 deeeep(deeeep.cpp) 描述 点点最近迷上了 deeeep(此 de 非彼 de),在研究一个特殊的最长树链问题 ...

  5. JS中数组和字符串具有的方法,以及substring,substr和slice的用法与区别

     String 对象属性 属性 描述 constructor 对创建该对象的函数的引用 length 字符串的长度 prototype 允许您向对象添加属性和方法 String 对象方法 方法 描述 ...

  6. 【刷题】BZOJ 5249 [2018多省省队联测]IIIDX

    Description [题目背景] Osu听过没?那是Konano最喜欢的一款音乐游戏,而他的梦想就是有一天自己也能做个独特酷炫的音乐游戏.现在,他在世界知名游戏公司KONMAI内工作,离他的梦想也 ...

  7. [洛谷P5137]polynomial

    题目大意:求:$$\sum\limits_{i=0}^na^{n-i}b^i\pmod{p}$$$T(T\leqslant10^5)$组数据,$a,b,n,p\leqslant10^{18}​$ 题解 ...

  8. 【BZOJ1042】硬币购物(动态规划,容斥原理)

    [BZOJ1042]硬币购物(动态规划,容斥原理) 题面 BZOJ Description 硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬 ...

  9. CSS截取中英文混合字符串长度

    <!doctype html> <html> <head> <meta http-equiv="content-type" content ...

  10. 模块(3)-使用__future__

    使用__future__ Python的每个新版本都会增加一些新的功能,或者对原来的功能作一些改动.有些改动是不兼容旧版本的,也就是在当前版本运行正常的代码,到下一个版本运行就可能不正常了. 从Pyt ...