25
2018
07

ES6中promise的用法

1、Promise的状态

Promise对象有三个状态:

1. 进行中(pending)

2. 成功(resolved)

3. 失败(rejected)

 

2、生成一个Promise对象

1. 构造函数

new Promise(function(resolve,reject){

});

resolve和reject函数是浏览器内部实现的,直接调用即可。

 

2. Promise.resolve

Promise.resolve()直接返回一个resolve状态的Promise对象

Promise.resolve可以用来生成一个then链

 

3. Promise.reject

Promise.reject()直接返回一个reject状态的Promise对象

 

3. Promise的then的用法

Promise的then永远返回一个新的Promise,Promise的catch是then(null,rejection)的语法糖,catch中也会返回一个新的Promise。

建议在Promise的then永远return或throw,不要只是执行一个函数。

例如:

var aPromise = new Promise(function (resolve) {

    resolve(100);

});

var thenPromise = aPromise.then(function (value) {

    console.log(value);

});

var catchPromise = thenPromise.catch(function (error) {

    console.error(error);

});

console.log(aPromise !== thenPromise); // => true

console.log(thenPromise !== catchPromise);// => true

=== 是严格相等比较运算符,我们可以看出这三个对象都是互不相同的,这也就证明了 then 和 catch 都返回了和调用者不同的promise对象。

1. Promise的then内部可以做三种事情:

(1). return 另一个promise

(2). return 一个同步值(或者undefined)

因为javascript函数无返回值时候,默认返回undefined,所以只是执行一个函数,不return,默认就是返回undefined。

返回一个同步值在Promise中会将同步代码包裹为promise,得到的还是一个promsie。返回一个同步值是有用处的,例如,

一个异步值在内存中做了缓存,可以直接从内存中拿到该值,直接返回,不必再调用异步接口。

getUserByName('xxx').then(function(user){

    if(imMemoryCache[user.id]){

        return inMemoryCache[user.id];

    }

    return getUserAccountById(user.id);

}).then(function(userAccount){

});

(3). throw 一个同步异常

 

2. Promise的一些写法

new Promise(function(resolve,reject){

    resolve(syncValue);

}).then(/*...*/)

//可以写成

Promise.resolve(syncValue).then(/*...*/)

//一个错误也可以写成

Promise.reject(new Error('...'))

这样无论成功或失败都可以后面的then和catch中捕获和继续操作

 

3. Promise的then中只能传递函数,如果为其他类型,例如另一Promise,会被解释为null,此时Promsie的值传递会穿透

例如:

Promise.resolve('foo').then(Promise.resolve('bar')).then(function(result){

    console.log(result);

});

//会被解释为:

Promise.resolve('foo').then(null).then(function(result){

    console.log(result);

});

第一个resolve的值会穿透到then,打印出foo。

 

4. then的四种写法的区别

// 写法一

f1().then(function () {

    return f2();

});

// 写法二

f1().then(function () {

    f2();

});

// 写法三

f1().then(f2());

// 写法四

f1().then(f2);

1. 写法1和4完全等价,f1值能传递到f2,f2的返回值也能继续向后面的then传递

2. 写法2相当于默认return undefined,无法向后面的then传递值

3. 写法3能够向后面传递f2的值,没有更深刻的解释(有懂的朋友请评论告知)

4. Promise的调用方法

每个then返回一个新的promise调用,这种写法被称为composing promises。

promise1.then(function(){

    return promise2;

}).then(function(){

    return promise3;

}).then(function(){

    return promise4;

}).catch(function(err){

    console.log(err);

});

5. Promise的并行执行

由于promise一旦被创建,就会立即执行,所以拿到一个Promise数组时候,其中的promise必然全部开始执行了。

因此要让一系列promise顺序执行,只能将promise放在一个函数中,在要执行的时候才去创建他,就是一个工厂

函数,promiseFactory。promise并行执行的代码应该如下:

function executeSequentially(promiseFactories){

    var res = Promsie.resolve();

    promiseFactories.forEach(function(promiseFactory){

        res = res.then(promiseFactory);

    });

    return res;

}

//工厂函数只是简单的创建一个promise

function promiseFactory(){

    return createAPromise();

}

6. Promise捕获错误

7. 实现一个Promise版本的ajax

//原生版本

function Http(){

}

Http.prototype = {

    get:function(opts){

        return this.ajax(opts);

    },

    post:function(){

        return this.ajax(opts);

    },

    ajax:function(opts){

        return Promise(function(resolve,reject){

            var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('...');

            var {url,method,data,async,success,fail} = options;

            var sendBody = null;

            var qs = Object.keys(data).reduce(function(cur,pre,index){

                return pre + '&' + encodeURIComponent(cur) + '=' + encodeURIComponent(data[cur]);

            },'').slice(1);

            if(medthod == 'get'){

                url += '?' + qs;

            }

            else if(medhot == 'post'){

                xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');

                sendBody = qs || null;

            }

            xhr.onreadystatechange = function(){

                if(xhr.readystate == 4){

                    if(xhr.status >= 200 && xhr.status < 300 || xhr.status == 304){

                        resolve(xhr,xhr.responseText);

                    }

                }

                else{

                    reject(xhr,xhr.responseText);

                }

            }

            xhr.open(method,url,async);

            xhr.send(sendBody);

        });

    }

}

//jquery版本

function Http(){

}

Http.prototype = {

    get:function(opts){

        return this.ajax(opts);

    },

    post:function(opts){

        return this.ajax(opts);

    },

    ajax:function(){

        return $.ajax(opts);

    }

}

 

原文链接:https://www.qiquanji.com/post/8265.html

本站声明:网站内容来源于网络,如有侵权,请联系我们,我们将及时处理。

gzh

微信扫码关注

更新实时通知

« 上一篇 下一篇 »

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。