资讯专栏INFORMATION COLUMN

Promise

laoLiueizo / 736人阅读

摘要:上面的代码指定了两个回调函数,第一个回调函数完成以后,会将结果作为参数传入到第二个回调函数。对进行处理捕捉错误方法其实是对的调用,用于指定发生错误时的回调函数。

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。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/81820.html

相关文章

  • Promise的几个扩展API总结

    摘要:的几个扩展总结描述和相反,当所有的被拒绝之后,方法执行完成的决议,如果存在一个执行完成的决议,方法则执行拒绝里边的所有实例反过来就好了执行到此执行到此描述忽略被拒绝的,只需要有一个完成的,方法就执行完成操作,如果全部的都被拒绝,方法执行拒绝 Promise的几个扩展API总结 1. Promise.none 描述: 和 Promise.all 相反,当所有的promise被拒绝之后,n...

    李义 评论0 收藏0
  • 异步发展流程 —— 手写一个符合 Promise/A+ 规范的 Promise

    摘要:构造函数的实现我们在使用的时候其实是使用关键字创建了一个的实例,其实是一个类,即构造函数,下面来实现构造函数。 showImg(https://segmentfault.com/img/remote/1460000018998456); 阅读原文 概述 Promise 是 js 异步编程的一种解决方案,避免了 回调地狱 给编程带来的麻烦,在 ES6 中成为了标准,这篇文章重点不是叙...

    UnixAgain 评论0 收藏0
  • Promise 对象的理解

    摘要:使用对象的好处在于可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。对象异步操作抛出错误,状态就会变为,就会调用方法指定的回调函数处理这个错误。 Promise 含义 Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了 Promise 对象。 所谓 P...

    church 评论0 收藏0
  • Promise 中的三兄弟 .all(), .race(), .allSettled()

    摘要:对于的来说基元函数包括组合函数的类型签名返回情况完成如果传入的可迭代对象为空,会同步地返回一个已完成状态的。相反,如果是在指定的时间之后完成,刚返回结果就是一个拒绝状态的从而触发方法指定的回调函数。在行中,对每个小任务得到的结果进行汇总。 为了保证的可读性,本文采用意译而非直译。 想阅读更多优质文章请猛戳GitHub博客,一年百来篇优质文章等着你! 从ES6 开始,我们大都使用的是 P...

    vspiders 评论0 收藏0
  • 实现Promise

    摘要:使用是极好的,它是如此有用以至于我觉得应该好好研究一下,甚至是实现一个简易的版本。构造函数检查参数例如是不是函数啊初始化,创建对象执行因此构造函数里面传入的是立即被执行的。 使用Promise是极好的,它是如此有用以至于我觉得应该好好研究一下Promise,甚至是实现一个简易的版本。实现之前,我们先来看看Promise的用途: 使用Promise callback hell Promi...

    xcc3641 评论0 收藏0
  • 【笔记】你不知道的JS读书笔记——Promise

    摘要:写在前面这一章的顺序对于未接触过使用过的童鞋而言略抽象了,前边几章主要为了说明和之前的异步方式相比有什么优势和它能解决什么问题,后边才详解的设计和各种场景下如何使用。建议先了解和简单使用过后再阅读,效果更佳。 写在前面:Promise这一章的顺序对于未接触过使用过Promise的童鞋而言略抽象了,前边几章主要为了说明Promise和之前的异步方式相比有什么优势和它能解决什么问题,后边才...

    mumumu 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<