es6 promise

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

//下面代码创造了一个Promise实例。
var promise = new Promise(function(resolve,reject){
    // to do

    if(){
       resolve(value);//成功
    }else{
        reject(values);//失败
    }
});
Promise构造函数接受一个函数作为参数,该函数的两个参数分别是 resolve reject 。它们是两个函数,由JavaScript引擎提供,不用自己部署。

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

//Promise实例生成以后,可以用then方法分别指定Resolved状态和Reject状态的回调函数。
promis.then(function(value){
    //success
},function(error){
    //fail
});

then 方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为Resolved时调用,第二个回调函数是Promise对象的状态变为Reject时调用。其中,第二个函数是可选的,不一定要提供。这两个函数都接受Promise对象传出的值作为参数。

//Promise新建后就会立即执行。
let promise = new Promise(function(resolve,reject){
    console.log('Promise');
    resolve();
});
promise.then(function(){
    console.log('Resolved!');
});
console.log('Hello!');
//Promise
//Hello!
//Resolved!
//上面代码中,Promise新建后立即执行,所以首先输出的是“Promise”。
//然后,then方法指定的回调函数,将在当前脚本所有同步任务执行完才会执行,所以“Resolved”最后输出。


下面是异步加载图片的例子。

function loadImgAsync(url){
    return new Promise(function(resolve,reject){
        var img = new Image();
        img.onload = function(){
            resolve(img);
        };
        img.onerror = function(){
            reject(new Error('wrong img!'));
        };
        img.src = url;
    })
}
//上面代码中,使用Promise包装了一个图片加载的异步操作。如果加载成功,就调用resolve方法,否则就调用reject方法。
如果调用 resolve 函数和 reject 函数时带有参数,那么它们的参数会被传递给回调函数。 reject 函数的参数通常是Error对象的实例,表示抛出的错误; resolve 函数的参数除了正常的值以外,还可能是另一个Promise实例,表示异步操作的结果有可能是一个值,也有可能是另一个异步操作,比如像下面这样。

var p1 = new Promise(function(resolve,reject){
    // to do
});
var p2 = new Promise(function(resolve,reject){
    resolve(p1);
});
//p1和p2都是Promise的实例,但是p2的resolve方法将p1作为参数,即一个异步操作的结果是返回另一个异步操作。
//注意,这时p1的状态就会传递给p2,也就是说,p1的状态决定了p2的状态。
//如果p1的状态是Pending,那么p2的回调函数就会等待p1的状态改变;
//如果p1的状态已经是Resolved或者Rejected,那么p2的回调函数将会立刻执行

var p3 = new Promise(function(resolve,reject){
    setTimeout(() => reject(new Error('Error!')),3000);
});
var p4 = new Promise(function(resolve,reject){
    setTimeout(() => resolve(p3),1000);
});

p4.then(result => console.log(result))
    .catch(error => console.log(error));
//Error: Error!
//上面代码中,p1是一个Promise,3秒之后变为rejected。p2的状态在1秒之后改变,resolve方法返回的是p1。
//由于p2返回的是另一个 Promise,导致p2自己的状态无效了,由p1的状态决定p2的状态。所以,后面的then语句都变成针对后者(p1)。
//又过了2秒,p1变为rejected,导致触发catch方法指定的回调函数。

1,Promise.prototype.then

Promise实例具有then方法,也就是说,then方法是定义在原型对象Promise.prototype上的。它的作用是为Promise实例添加状态改变时的回调函数。前面说过,then方法的第一个参数是Resolved状态的回调函数,第二个参数(可选)是Rejected状态的回调函数。

2,Promise.prototype.catch

Promise.prototype.catch 方法是 .then(null, rejection) 的别名,用于指定发生错误时的回调函数。
var promise = new Promise(function(resolve,reject){
    throw new Error('test!');
});
promise.catch(function(error){
    console.log(error);
});
//Error: test!

上面代码中, promise 抛出一个错误,就被 catch 方法指定的回调函数捕获。注意,上面的写法与下面两种写法是等价的。
var promise = new Promise(function(resolve,reject){
    try{
        throw new Error('test!');
    }catch (e){
        reject(e);
    }
});
promise.catch(function(error){
    console.log(error);
});
//写法2
var promise1 = new Promise(function(resolve,reject){
    reject(new Error('tese!'));
});
promise1.catch(function(error){
    console.log(error);
});
//比较上面两种写法,可以发现reject方法的作用,等同于抛出错误。

3,promise.all()

Promise.all 方法用于将多个Promise实例,包装成一个新的Promise实例
var p = Promise.all([p1,p2,p3]);
//上面代码中,Promise.all方法接受一个数组作为参数,p1、p2、p3都是Promise对象的实例,
//如果不是,就会先调用下面讲到的Promise.resolve方法,将参数转为Promise实例,再进一步处理。
//(Promise.all方法的参数可以不是数组,但必须具有Iterator接口,且返回的每个成员都是Promise实例。)

p的状态由p1p2p3决定,分成两种情况。

(1)只有p1p2p3的状态都变成fulfilledp的状态才会变成fulfilled,此时p1p2p3的返回值组成一个数组,传递给p的回调函数。

(2)只要p1p2p3之中有一个被rejectedp的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

4,premise.race()

Promise.race 方法同样是将多个Promise实例,包装成一个新的Promise实例
var p = Promise.race([p1,p2,p3]);
//上面代码中,只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。
//那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

//Promise.race方法的参数与Promise.all方法一样,如果不是 Promise 实例,
//就会先调用下面讲到的Promise.resolve方法,将参数转为 Promise 实例,再进一步处理
//下面是一个例子,如果指定时间内没有获得结果,就将Promise的状态变为reject,否则变为resolve。
const p = Promise.race([
    fetch('/resource-that-may-take-a-while'),
    new Promise(function(resolve,reject){
        setTimeout(() => reject(new Error('request timeout')),5000);
    })
]);
p.then(response => console.log(response))
    .catch(error => console.log(error));
//上面代码中,如果5秒之内fetch方法无法返回结果,变量p的状态就会变为rejected,从而触发catch方法指定的回调函数

5,promise.resolve()

有时需要将现有对象转为Promise对象,Promise.resolve方法就起到这个作用
//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 p = Promise.resolve(thenable);
p.then(s => console.log(s));//42
//上面代码中,thenable对象的then方法执行后,对象p1的状态就变为resolved,从而立即执行最后那个then方法指定的回调函数,输出42
(3)参数不是具有then方法的对象,或根本就不是对象
如果参数是一个原始值,或者是一个不具有then方法的对象,则Promise.resolve方法返回一个新的Promise对象,状态为Resolved
var p = Promise.resolve('hello!');
p.then(s => console.log(s));//hello!
//上面代码生成一个新的Promise对象的实例p。
//由于字符串Hello不属于异步操作(判断方法是它不是具有then方法的对象),
//返回Promise实例的状态从一生成就是Resolved,所以回调函数会立即执行。
//Promise.resolve方法的参数,会同时传给回调函数。
(4)不带有任何参数
Promise.resolve方法允许调用时不带参数,直接返回一个Resolved状态的Promise对象。
所以,如果希望得到一个Promise对象,比较方便的方法就是直接调用Promise.resolve方法。
var p = Promise.resolve();
p.then(function(){
    // to do
});
需要注意的是,立即 resolve 的Promise对象,是在本轮“事件循环”(event loop)的结束时,而不是在下一轮“事件循环”的开始时。

setTimeout(function () {
    console.log('three');
}, 0);

Promise.resolve().then(function () {
    console.log('two');
});

console.log('one');

// one
// two
// three
//上面代码中,setTimeout(fn, 0)在下一轮“事件循环”开始时执行,
//Promise.resolve()在本轮“事件循环”结束时执行,console.log(’one‘)则是立即执行,因此最先输出。

6,promise.reject()

Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected
var p = Promise.reject('error');
//等同于
var p = new Promise((resolve,reject) => reject('error'));
p.then(null,s => console.log(s));
上面代码生成一个Promise对象的实例p,状态为rejected,回调函数会立即执行。

注意,Promise.reject()方法的参数,会原封不动地作为reject的理由,变成后续方法的参数。
这一点与Promise.resolve方法不一致。
const thenable = {
    then(resolve,reject){
        reject('error');
    }
};
Promise.reject(thenable)
    //.catch(e =>{
    //    console.log(e === thenable);
    //});
    .catch(e => console.log(e === thenable));
// true
//上面代码中,Promise.reject方法的参数是一个thenable对象,执行以后,
//后面catch方法的参数不是reject抛出的“出错了”这个字符串,而是thenable对象。




















  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值