ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
## 一、概述 Promise 是异步编程的一种解决方案,比传统的解决方案:回调函数和事件,更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生的提供了Promise对象。 所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。 Promise可以被链式调用: ![](https://img.kancloud.cn/50/f7/50f73b2ae220804ebd08f2b7b0700655_691x271.png) ## 二、对象状态 Promise对象有三个状态: 1. pending:初始值,不是fulfilled,也不是rejected 2. fulfilled:代表操作成功 3. rejected:代表操作失败 >[danger] 一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。 ## 三、基本用法 1、定义Promise实例,包含业务代码执行,并抛出成功/失败信号; ```javascript const promise = new Promise(function(resolve, reject) { // ... 业务操作代码 if (/* 异步操作成功 */){ resolve(value);//业务操作最后是成功的,就要把状态改为成功,且通过resolve把value值抛出去,传递给then函数里面排名第一位的参数,也就是成功逻辑处理函数,作为该函数的入口参数传递过去; } else { reject(error);//如果业务操作代码中间发生异常,就要把状态改为失败,且把error值抛出去,传递给then函数里面位于排名第二位的参数,也就是失败逻辑处理函数,作为该函数的入口参数传递过去; } }); ``` >[danger] > 1、Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署(不用自己提供这两个函数的实现,直接调用即可)。 > 2、resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去; > 3、reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。 2、根据上面实例成功/失败信号,用then方法分别指定resolved状态和rejected状态的回调函数; ```javascript promise.then(function(value) { // 接收到成功信号的时候,且从实例的resolve获取resolve里面的数据,执行的代码定义在这里 }, function(error) { // 接收到失败信号的时候,且从实例的reject获取reject里面的数据,执行的代码定义在这里 }); ``` then方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为resolved时调用,第二个回调函数是Promise对象的状态变为rejected时调用。其中,第二个函数是可选的,不一定要提供。这两个函数都接受Promise对象传出的值(第1步里面的resolve/reject传出来的)作为参数。 ## 四、实例 1、简单的实例 ``` //1、定义实例 let promise = new Promise(function(resolve, reject) { console.log('Promise'); //业务代码脚本 resolve(); //未带值 }); // 2、设定回调函数 promise.then(function() { //这里也就没有入参 console.log('resolved.'); }); console.log('Hi!'); ``` ``` // Promise // Hi! // resolved 上面代码中,Promise 新建后立即执行,所以首先输出的是Promise。然后,then方法指定的回调函数,将在当前脚本所有业务代码执行完才会执行,所以resolved最后输出。 ``` 2、较复杂的实例 ``` const getJSON = function(url) { const promise = new Promise(function(resolve, reject){ const handler = function() { if (this.readyState !== 4) { return; } if (this.status === 200) { resolve(this.response); } else { reject(new Error(this.statusText)); } }; const client = new XMLHttpRequest(); client.open("GET", url); client.onreadystatechange = handler; client.responseType = "json"; client.setRequestHeader("Accept", "application/json"); client.send(); }); return promise; }; getJSON("/posts.json").then(function(json) { console.log('Contents: ' + json); }, function(error) { console.error('出错了', error); }); ```