全面理解Javascript中Promise

全面理解Javascript中Promise

最近在学习Promise的时候,在网上收集了一些资料,发现很多的知识点不够系统,所以小编特意为大家整理了一些自认为
比较好的文章,供大家更好地学习JS中非常有趣的Promise

Promise概念

2015 年 6 月,ECMAScript 6 的正式版 终于发布了。

ECMAScript 是 JavaScript 语言的国际标准,JavaScript 是 ECMAScript 的实现。ES6 的目标,是使得 JavaScript 语言可以用来编写大型的复杂的应用程序,成为企业级开发语言。

–Promise知识JS的一个新对象,为的就是解决js在处理异步的时候产生的多成回调的问题,那么在Promise纳入ES6的规范之前,一些优秀
的框架是如何解决这种异步回调的问题的呢?
在JQuery这个传奇的框架中,已经有方法解决上述问题的方案了,那就是jQuery的deferred对象,还没有接触到这个对象的小同学可以想去
了解一下,推荐一篇博文jQuery的deferred对象详解。当我了解到JQ中
deferred对象的时候,就发现Promise的奥秘其实很简单,跟deferred对象的实现方法有着异曲同工之妙。下面开始从Promise的基础,Promise应用出发带大家了解Promise的美妙

Promise基础

–ES6 原生提供了 Promise 对象。

所谓 Promise,就是一个对象,用来传递异步操作的消息。它代表了某个未来才会知道结果的事件(通常是一个异步操作),并且这个事件提供统一的 API,可供进一步处理。

Promise 对象有以下两个特点。

(1)对象的状态不受外界影响。Promise 对象代表一个异步操作,有三种状态:Pending(进行中)、Resolved(已完成,又称 Fulfilled)和 Rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是 Promise 这个名字的由来,它的英语意思就是「承诺」,表示其他手段无法改变。

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

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

Promise 也有一些缺点。首先,无法取消 Promise,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,Promise 内部抛出的错误,不会反应到外部。第三,当处于 Pending 状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

var promise = new Promise(function(resolve, reject) {
 if (/* 异步操作成功 */){
 resolve(value);
 } else {
 reject(error);
 }
});

promise.then(function(value) {
 // success
}, function(value) {
 // failure
});

Promise 构造函数接受一个函数作为参数,该函数的两个参数分别是 resolve 方法和 reject 方法。

如果异步操作成功,则用 resolve 方法将 Promise 对象的状态,从「未完成」变为「成功」(即从 pending 变为 resolved);

如果异步操作失败,则用 reject 方法将 Promise 对象的状态,从「未完成」变为「失败」(即从 pending 变为 rejected)。

使用Promise组织你的AJAX

//创建一个Promise实例,获取数据。并把数据传递给处理函数resolve和reject。需要注意的是Promise在声明的时候就执行了。
var getUserInfo=new Promise(function(resolve,reject){
    $.ajax({
        type:"get",
        url:"index.aspx",
        success:function(data){
            if(data.Status=="1"){
                resolve(data.ResultJson)//在异步操作成功时调用
            }else{
                reject(data.ErrMsg);//在异步操作失败时调用
            }
        }
    });
})
//另一个ajax Promise对象,
var getDataList=new Promise(function(resolve,reject){
    $.ajax({
        type:"get",
        url:"index.aspx",
        success:function(data){
            if(data.Status=="1"){
                resolve(data.ResultJson)//在异步操作成功时调用
            }else{
                reject(data.ErrMsg);//在异步操作失败时调用
            }
        }
    });
})
//Promise的方法then,catch方法
getUserInfo.then(function(ResultJson){
    //通过拿到的数据渲染页面
}).catch(function(ErrMsg){
    //获取数据失败时的处理逻辑
})
//Promise的all方法,等数组中的所有promise对象都完成执行
Promise.all([getUserInfo,getDataList]).then(function([ResultJson1,ResultJson2]){
    //这里写等这两个ajax都成功返回数据才执行的业务逻辑
})

写一个自己的Promise,揭开Promise的神秘面纱

–Promise的规范

1.一个promise可能有三种状态:等待(pending)、已完成(fulfilled)、已拒绝(rejected)
2.一个promise的状态只可能从“等待”转到“完成”态或者“拒绝”态,不能逆向转换,同时“完成”态和“拒绝”态不能相互转换
3.promise必须实现then方法(可以说,then就是promise的核心),而且then必须返回一个promise,同一个promise的then可以调用多次,并且回调的执行顺序跟它们被定义时的顺序一致
4.then方法接受两个参数,第一个参数是成功时的回调,在promise由“等待”态转换到“完成”态时调用,另一个是失败时的回调,在promise由“等待”态转换到“拒绝”态时调用。同时,then可以接受另一个promise传入,也接受一个“类then”的对象或方法,即thenable对象。

–promise原理分析
可以看到promise的规范并不是很多,下面我们一边分析promise一边自己写一个promise的实现。Promise实现的大致思路如下:

  构造函数Promise接受一个函数resolver,可以理解为传入一个异步任务,resolver接受两个参数,一个是成功时的回调,一个是失败时的回调,这两参数和通过then传入的参数是对等的。

其次是then的实现,由于Promise要求then必须返回一个promise,所以在then调用的时候会新生成一个promise,挂在当前promise的_next上,同一个promise多次调用都只会返回之前生成的_next。

由于then方法接受的两个参数都是可选的,而且类型也没限制,可以是函数,也可以是一个具体的值,还可以是另一个promise。下面是then的具体实现:

Promise.prototype.then = function(resolve, reject) {  
    var next = this._next || (this._next = Promise());  
    var status = this.status;  
    var x;  

    if('pending' === status) {  
        isFn(resolve) && this._resolves.push(resolve);  
        isFn(reject) && this._rejects.push(reject);  
        return next;  
    }  

    if('resolved' === status) {  
        if(!isFn(resolve)) {  
            next.resolve(resolve);  
        } else {  
            try {  
                x = resolve(this.value);  
                resolveX(next, x);  
            } catch(e) {  
                this.reject(e);  
            }  
        }  
        return next;  
    }  

    if('rejected' === status) {  
        if(!isFn(reject)) {  
            next.reject(reject);  
        } else {  
            try {  
                x = reject(this.reason);  
                resolveX(next, x);  
            } catch(e) {  
                this.reject(e);  
            }  
        }  
        return next;  
    }  
};

参考文献
jQuery的deferred对象详解
JavaScript进阶之路
Javascript 中的神器

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JavascriptPromise是一种用于处理异步操作的封装对象。在进行文件下载时,可以利用Promise来管理下载过程异步操作。 首先,我们需要创建一个Promise对象,并将下载操作封装在其。下载通常涉及到向服务器发送请求、接收响应并处理数据。可以使用XMLHttpRequest对象来实现这些步骤。 以下是一个使用Promise进行文件下载的示例代码: ```javascript function downloadFile(url) { return new Promise(function(resolve, reject) { var xhr = new XMLHttpRequest(); xhr.open('GET', url, true); xhr.responseType = 'blob'; xhr.onload = function() { if (xhr.status === 200) { resolve(xhr.response); } else { reject(Error('下载文件时出错')); } }; xhr.onerror = function() { reject(Error('下载文件时出错')); }; xhr.send(); }); } // 使用示例 downloadFile('http://example.com/file.pdf') .then(function(blob) { // 下载成功后的处理逻辑 var url = URL.createObjectURL(blob); window.location.href = url; // 在当前页面打开下载链接 }) .catch(function(error) { // 下载失败时的处理逻辑 console.error(error); }); ``` 在上述代码,首先创建一个Promise对象,并在其定义了下载的异步操作。在下载成功时,调用resolve方法并传递服务器响应的数据;在下载失败时,调用reject方法并传入一个Error对象。 然后,通过调用then方法来处理下载成功的响应,并在该回调函数进行文件处理。如果下载失败,则通过调用catch方法来捕获错误,并在该回调函数处理错误。 这样,我们就可以通过Promise来管理文件下载操作,并根据下载的结果执行相应的逻辑。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值