Promise

Promise对象是一种异步编程的解决方案,比传统的解决方案——会掉函数和事宜——更合理和壮大。
Promise有三种状况:pending(举行中)、Resolved(Fulfilled,已完成)和Rejected(已失利);而且状况一旦转变,就不会再发作转变,Promise对象的状况只需两种能够:从Pending变成Resolved和从Pending变成Rejected。只需这两种状况发作了,状况就凝结了,不会再变了。Promise有一些瑕玷,就是没法作废,一旦新建它就会实行,没法半途作废;其次假如不设置回调函数,Promise内部抛出的毛病,不会回响反映到外部;第三Pending状况时,没法得知现在希望到哪个阶段。

基础用法

Promise组织函数接收一个函数作为参数,该函数参数分别是resolve和reject要领。假如胜利,则用resolve将Promise的状况改成胜利,即从Pending变成resolved;假如异步失利,则从Pending改成rejected。

基础用法

var promise = new Promise(function(resolve, reject){
    if(/*异步操纵胜利*/){
        resolve(value);
    } else{
        reject(error);
    }
});
promise.then(function(value){
    //success
}, function(value){
    //failure
});

一个简朴有用的例子

function timeout(ms){
    return new Promise((resolve) => {
        setTimeout(resolve, ms);
    });
}

timeout(100).then(()=>{
    console.log('done');
})

假如用Promise对象完成Ajax操纵

var getJSON = function(url){
    var promise = new Promise(function(resolve, reject){
        var client = new XMLHttpRequest();
        client.open("GET", url);
        client.onreadystatechange = handler;
        client.responseType = "json";
        client.setRequestHeader("Accept", "application/json");
        client.send();
        
        function handler(){
            if(this.status == 200){
                resolve(this.response);
            }else {
                reject(new Error(this.statusText));
            }
        }
        
        return promise;
    })
}

getJSON("/posts.json").then(function(json){
    console.log("Contents:" + json);
}, function(error){
    console.error('出错了', error);
})

在resolve的要领参数除了正常值认为,还能够能是另一个Promise实例。

Promise的链式操纵:Promise.prototype.then

Promise.prototype.then返回的是一个新的Promise对象,因而能够写成链式的。

getJSON("/posts.json").then(function(json){
    return json.post;
}).then(function(){
    //proceed
})

上面的代码指定了两个回调函数,第一个回调函数完成今后,会将效果作为参数传入到第二个回调函数。
假如第一个回调函数返回的是Promise对象,如许后一个函数挪用就将守候该Promise对象有了运转效果,才会进一步挪用。

getJSON("/post/1.json").then(function(post){
    return getJSON(post.commentURL);
}).then(function(comments){
    //对comments举行处置惩罚
})

捕捉毛病:Promise.prototype.catch要领

Promise.prototype.catch实际上是对Promise.prototype.then(null, rejection)的挪用,用于指定发作毛病时的回调函数。

Promise.prototype.catch 对毛病具有“冒泡”性子,会一向向后通报,直到被捕捉,也就是错我老是被下一个catch语句捕捉。

getJSON("/post/1.json").then(function(post) {
  return getJSON(post.commentURL);
}).then(function(comments) {
  // some code
}).catch(function(error) {
  // 处置惩罚前两个回调函数的毛病
});

Promise.all要领

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

这个要领接收一个数组作为参数,p1,p2,p3都是Promise对象的实例。p的终究状况取决于参数对象数组的状况,上例中就是p1,p2,p3来决议的。假如这三个都是fulfilled,那末p的状况就是fulfilled;假如p1,p2,p3中有一个是rejected,p的状况就是rejected.那末p的状况就是reject,会通报给p的回调函数。

// 天生一个Promise对象的数组
var promises = [2, 3, 5, 7, 11, 13].map(function(id){
  return getJSON("/post/" + id + ".json");
});

Promise.all(promises).then(function(posts) {
  // ...  
}).catch(function(reason){
  // ...
});

Promise.resolve要领,Promise.reject要领

将现有对象转我Promise对象,Promise.resolve要领就起到这个作用。

var jsPromise = Promise.resolve($.ajax('/whatever.json'));

上面jQuery天生defferred对象,转为一个新的ES6的Promise对象。
假如Promise.resolve要领的参数,不具有then要领的对象(又称thenable对象),则返回一个新的Promise对象,且他的状况为fulfilled.

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

上面天生一个新的Promise对象的实例p,它的状况为fulfilled。
Promise.reject(reason)要领也会返回一个新的Promise实例,该实例的状况为rejected,Promise.reject要领的参数reason,会被通报给实例的回调函数。

async函数

async函数是用来庖代回调函数的另一种要领。只需函数之前加上async的关键字,就表明该函数内部有异步操纵。该异步操纵返回一个Promise对象,前面用await关键字说明。当函数实行的时刻,一旦碰到await就立马返回,等接触到异步操纵完成,再接着实行函数体内背面的语句。

async function getStockPrice(symbol, currency) {
    let price = await getStockPrice(symbol);
    return convert(price, currency);
}

函数前面加了一个async表明该函数将返回一个Promise对象,挪用该函数时,碰到await关键字,马上返回背面的表达式发生的Promise对象,不再实行函数体背面的语句。等getStockPrice完成,在自动回到函数体内,实行剩下的语句。

function timeout(ms) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
}

async function asyncValue(value) {
  await timeout(50);
  return value;
}

上面代码中,asyncValue函数前面有async关键字,表明函数体内有异步操纵。实行的时刻,碰到await语句就会先返回,比及timeout函数实行终了,再返回value。

    原文作者:jyren_Rachel
    原文地址: https://segmentfault.com/a/1190000008533665
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞