JavaScript之Promise

一、概念:

        ECMAScript是JavaScript语言的国际标准,JavaScript是ECMAScript的实现。2015年6月ECMAScript 6正式版发布,目标是使得JavaScript语言可以用来编写大型的复杂的应用程序,成为企业级开发语言。ECMAscript 6原生提供了Promise对象,Promise对象代表了未来将要发生的事件,用来传递异步操作的消息。Promise对象有以下两个特点:

        1、Promise对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:

                ①Pending:初始状态,不是成功也不是失败状态;

                ②Resolved:意味着操作成功完成;

                ③Rejected:意味着操作失败。

        只有异步操作的结果可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。

        2、一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象状态改变,只有两种可能:从Pending变为 Resolved和从Pending变为Rejected。只要这两种情况发生,状态就固定了,不会再变了,会一直保持这个结果。就算改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。

二、作用:

        有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise对象提供统一的接口,使得控制异步操作更加容易。

三、使用:

        1、使用单个的Promise对象:

        要想使用Promise对象、可以使用new来调用Promise的构造器来进行实例化。Promise构造函数以一个含有resolve(成功)和 reject(失败)两个回调函数为输入参数的函数为入参。在该函数中执行一些操作(例如异步),如果一切都正常,则调用 resolve函数把值传出去,否则调用reject函数把值传出去。传出去的值最终通过该Promise对象的then(obj)方法或者catch(obj)方法获取并得到处理,这里的then(obj)和catch(obj)方法的入参即为通过resolve函数和reject函数传出的值。

        ①使用之前需要确保浏览器要支持Promise,可执行如下代码进行测试:

扫描二维码关注公众号,回复: 8969108 查看本文章
new Promise(function () {});

        ②首先定义一个以resolve和reject为入参的函数,并在其中做一些异步操作,并最终根据成功或失败调用resolve或reject方法:

function handle(resolve, reject) {
    var timeOut = Math.random() * 2;
    console.log('set timeout:' + timeOut + ' seconds.');
    setTimeout(function () {
        if (timeOut < 1) {
            console.log('call resolve()...');
            resolve('200 OK');
        }else {
            console.log('call reject()...');
            reject('timeout is ' + timeOut + ' seconds.');
        }
    }, timeOut * 1000);
}

        ③创建Promise对象,以步骤2中的函数为入参,同时定义Promise对象的then()方法和catch()方法:

var promise = new Promise(handle);
var ret1 = promise.then(function (result) {
    console.log('成功:' + result);
});
var ret2 = promise.catch(function (reason) {
    console.log('失败:' + reason);
});

        Promise对象的then()方法和catch()方法都会返回Promise对象本身,所以可以采用级联,上述代码可以简化为:

new Promise(handle).then(function (result) {
    console.log('成功:' + result);
}).catch(function (reason) {
    console.log('失败:' + reason);
});

很明显:Promise最大的好处是在异步执行的流程中,把执行代码和处理结果的代码清晰地分离。

        2、使用多个的Promise对象:

        ①如果有多个Promise任务,并要求它们并行执行,所有任务都执行完成后再往下执行,可以使用Promise.all(arr)方法:

var promise1 = new Promise(function (resolve, reject) {
    setTimeout(resolve, 500, 'promise1');
});
var promise2 = new Promise(function (resolve, reject) {
    setTimeout(resolve, 600, 'promise2');
});
//同时执行promise1和promise2,并在它们都完成后执行then:
Promise.all([promise1, promise2]).then(function (results) {
    console.log(results); //获得一个Array: ['promise1', 'promise1']
});

        ②如果有多个Promise任务,只要有一个任务执行完成就可以往下执行,多个Promise任务是为了容错,可以使用Promise.race(arr)方法:

var promise1 = new Promise(function (resolve, reject) {
    setTimeout(resolve, 500, 'promise1');
});
var promise2 = new Promise(function (resolve, reject) {
    setTimeout(resolve, 600, 'promise2');
});
//由于promise1执行较快,Promise的then()将获得结果'promise1',promise2执行较慢,等它有执行结果后就被丢弃了
Promise.race([promise1, promise2]).then(function (results) {
    console.log(results); //promise1
});

        3、Promise.resolve(obj)方法和Promise.reject(obj)方法:

        ①Promise.resolve(obj)方法将指定的对象obj转化为Promise对象。如果obj是不具有then方法的对象(又称thenable对象),则返回一个新的Promise对象,且它的状态为Resolved,也就是说可以被Promise对象的then()方法获取到;如果obj是一个Promise对象的实例,则会被原封不动地返回。

var promise = Promise.resolve('Hello');
promise.then(function (str){
    console.log(str)
}); //Hello

        ②Promise.reject(obj)方法将指定的对象obj转化为Promise对象。如果obj是不具有then方法的对象(又称thenable对象),则返回一个新的Promise对象,且它的状态为Rejected,也就是说可以被Promise对象的catch()方法获取到;如果obj是一个Promise对象的实例,则会被原封不动地返回。

var promise = Promise.reject('Hello');
promise.catch(function (str){
    console.log(str)
}); //Hello

参考:https://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000/0014345008539155e93fc16046d4bb7854943814c4f9dc2000

http://www.runoob.com/w3cnote/javascript-promise-object.html

发布了108 篇原创文章 · 获赞 31 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/lzghxjt/article/details/83476829