JavaScript 之 Promise

zluotan 2年前
   <p>Promise 对象用于异步计算。一个 Promise 对象表示一个现在或者将来或者永不可用的值。</p>    <h2>语法</h2>    <pre>  <code class="language-javascript">new Promise(      /** executor */      function(resolve, reject){          ...      }  )  </code></pre>    <h2>参数</h2>    <ul>     <li> <p>executor:</p> <p>一个函数,该函数的参数为:resolve 和 reject。executor 函数在实现 Promise 对象时立即被调用,甚至在 Promise 的构造函数返回之前就被执行,</p> <p>resolve 和 reject 会被传入。resolve 和 reject 都是函数,executor 通常初始化一些异步工作,之后,一旦完成,会调用 resolve 函数清理 promise,</p> <p>或者在发送错误时调用 reject 拒绝 promise。</p> </li>    </ul>    <h2>描述</h2>    <p>Promise 对象是一个 ’值‘的代理,该’值‘在 promise 对象创建时可能是未知的。它允许你为异步操作的事件结果“成功返回的值”或“失败”绑定一个处理方法。</p>    <p>这使得异步方法可以像同步方法那样返回值;不同于立即返回最终结果,异步方法返回一个 promise 对象,可以在未来提供一个值。</p>    <p>Promise 有以下几种状态:</p>    <ul>     <li>pending:初始状态,既不是 fulfilled 也不是 rejected。</li>     <li>fulfilled:表示成功完成操作。</li>     <li>rejected:表示该操作失败。</li>    </ul>    <p>pending 状态的 promise 对象可以通过一个值转换为 fulfilled 或者 rejected 状态。当状态发送转换时,promise.then 绑定的方法就会被调用。</p>    <p>因为 Promise.prototype.then 和 Promise.prototype.catch 方法返回 promise 对象,所以它们可以被链式调用(一种被称为 composition 的操作)。</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/835119a5c72db92a1ae89730a7af1251.png"></p>    <h2>属性</h2>    <ul>     <li> <p>Promise.length</p> <p>长度属性,值为 1,构造器参数的数量。</p> </li>     <li> <p>Promise.prototype</p> <p>表示 Promise 构造器的原型。</p> </li>    </ul>    <h2>方法</h2>    <ul>     <li> <p>Promise.all(iterable)</p> <p>这个方法返回一个新的 promise 对象,该 promise 对象在 iterable 里所有的 promise 对象都成功的时候才会触发成功,</p> <p>一旦有任何一个 iterable 里面的 promise 对象失败则立即触发该 promise 对象的失败。这个新的 promise 对象在触发成功状态以后,</p> <p>会把一个包含 iterable 里所有 promise 返回值的数组作为成功回调的返回值,顺序跟 iterable 的顺序保持一致;</p> <p>如果这个新的 promise 对象触发了失败状态,它会把 iterable 里第一个触发失败的 promise 对象的错误信息作为它的失败错误信息。</p> <p>Promise.all 方法常被用于处理多个 promise 对象的状态集合。</p> </li>     <li> <p>Promise.race(iterable)</p> <p>当 iterable 参数里的任意一个子 promise 成功或失败后,父 promise 马上也会用子 promise 的成功返回值或失败详情作为参数调用</p> <p>父 promise 绑定的相应方法,并返回该 promise 对象。</p> </li>     <li> <p>Promise.reject(reason)</p> <p>调用 Promise 的 reject 方法,并返回这个 Promise 对象。</p> </li>     <li> <p>Promise.resolve(value)</p> <p>用成功值 value 完成一个 Promise 对象。如果该 value 带有 then 方法,返回的 Promise 对象会跟随这个 value,采用这个 value 的最终状态;</p> <p>否则的话返回值会用这个 value 满足(fulfilled)返回的 Promise 对象。</p> </li>    </ul>    <h2>Promise 原型</h2>    <h2>属性</h2>    <ul>     <li> <p>Promise.prototype.constructor</p> <p>返回创建了实例原型的函数,默认为 Promise 函数。</p> </li>    </ul>    <h2>方法</h2>    <ul>     <li> <p>Promise.prototype.catch(onRejected)</p> <p>添加一个 rejection 回调到当前 promise ,返回一个新的 promise。如果这个回调被调用,新 promise 将以它的返回值来 resolve,否则如果当前</p> <p>promise 进入 fulfilled 状态,则以当前 promise 的成功结果作为新 promise 的成功结果。</p> </li>     <li> <p>Promise.prototype.then(onFulfilled, onRejected)</p> <p>添加一个成功和失败回调到当前 promise,返回一个新的 promise,将以回调的返回值来 resolve。</p> </li>    </ul>    <h2>示例</h2>    <p>下面例子展示了 Promise 的机制。每当按钮被点击时,testPromise() 方法就会被执行。该方法会创建一个用 window.setTimeout 1 到 3 秒后完成的 promise。</p>    <p>这里通过了 p1.then 方法的满足回调,简单的输出了 promise 的满足过程,这些输出显示了该方法的同步部分是如何和 promise 的异步完成解耦的。</p>    <pre>  <code class="language-javascript"><button onclick="testPromise();">点我</button>  <div id="log"></div>  <script>      'use strict';      var promiseCount = 0;      function testPromise() {          var thisPromiseCount = ++promiseCount;            var log = document.getElementById('log');          log.insertAdjacentHTML('beforeend', thisPromiseCount + ') 开始(同步代码开始)<br/>');            // 创建一个新的promise: 然后用完成这个promise          var p1 = new Promise(function (resolve, reject) {              // 完成函数带着完成(resolve)或拒绝(reject)promise 的能力被执行              log.insertAdjacentHTML('beforeend', thisPromiseCount + ') Promise开始(异步代码开始)<br/>');                // 这只是个创建异步完成的示例              window.setTimeout(function () {                  // 我们满足(fullfil)了这个promise!                  resolve(thisPromiseCount)              }, Math.random() * 2000 + 1000);          });            // 定义当promise被满足时应做什么          p1.then(function (val) {              // 输出一段信息和一个值              log.insertAdjacentHTML('beforeend', val + ') Promise被满足了(异步代码结束)<br/>');          });            log.insertAdjacentHTML('beforeend', thisPromiseCount + ') 建立了Promise(同步代码结束)<br/><br/>');      }  </script>  </code></pre>    <p> </p>    <p>来自:http://svend.cc/posts/36621/</p>    <p> </p>