diff options
Diffstat (limited to 'files/zh-cn/mozilla/javascript_code_modules/promise.jsm/promise/index.html')
-rw-r--r-- | files/zh-cn/mozilla/javascript_code_modules/promise.jsm/promise/index.html | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/files/zh-cn/mozilla/javascript_code_modules/promise.jsm/promise/index.html b/files/zh-cn/mozilla/javascript_code_modules/promise.jsm/promise/index.html new file mode 100644 index 0000000000..947fd3acdc --- /dev/null +++ b/files/zh-cn/mozilla/javascript_code_modules/promise.jsm/promise/index.html @@ -0,0 +1,226 @@ +--- +title: Promise +slug: Mozilla/JavaScript_code_modules/Promise.jsm/Promise +translation_of: Mozilla/JavaScript_code_modules/Promise.jsm/Promise +--- +<p><strong>Promise对象代表暂时不可用的值。</strong></p> + +<p>一个已存在的promise引用可以通过不同的方式被接收,如作为异步API的返回值。一旦得到一个promise对象,就可以调用其 <a href="#then()" title="#then()"><code>then()</code></a> 方法,以在其值可用时或者出现异常时执行一个动作。</p> + +<p>可以通过 <a href="https://developer.mozilla.org/zh-CN/docs/Mozilla/JavaScript_code_modules/Promise.jsm/Promise$edit#Constructor" title="#Constructor"><code>new Promise()</code></a><code> </code>方法创建Promise对象,当使用一个已存在的Promise对象时,不需要引入 <a href="https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Promise.jsm" title="#defer()"><code>Promise.jsm</code></a> 模块。</p> + +<p>promise内部状态可为以下三种之一:</p> + +<ul> + <li><strong>未完成状态(pending)</strong>,此时完成值还不可用,它是唯一一个能够转换为其他状态的状态。</li> + <li><strong>已完成状态(fulfilled)</strong>,此时<em>完成值</em>可用,完成值与promise永久绑定,可为任意值,包括<code>undefined。</code></li> + <li><strong>拒绝状态(rejected)</strong>,出现错误时,<em>拒绝理由</em>与promise永久绑定,可为任意值,包括<code>undefined</code>,一般情况下为 <a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Error" title="/en-US/docs/JavaScript/Reference/Global_Objects/Error"><code>Error</code></a> 对象。</li> +</ul> + +<div class="note"> +<p><strong>备注: </strong>使用promise时,应该始终对异常(拒绝理由)进行处理或报告。如果你看见了"<strong>A promise chain failed to handle a rejection</strong>"的错误信息,你可能就需要检查你的代码。参见下面的 <a href="https://developer.mozilla.org/zh-CN/docs/Mozilla/JavaScript_code_modules/Promise.jsm/Promise$edit#Handling_errors_and_common_pitfalls">异常处理和常见误区</a>。</p> +</div> + +<h2 id="文档约定">文档约定</h2> + +<p>文档规定,完成值的类型通过尖括号内的内容指定。如 <code style="font-style: normal;"><a href="/en-US/docs/JavaScript_OS.File/OS.File_for_the_main_thread#OS.File.exists()" title="/en-US/docs/JavaScript_OS.File/OS.File_for_the_main_thread#OS.File.exists()">OS.File.exists</a></code> 方法返回一个完成值类型为<code>boolean</code>的promise:</p> + +<pre>Promise<boolean> exists(string path); +</pre> + +<p>拒绝理由可能在function文档中单独规定,除非特别指定,一般使用 <a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Error" title="/en-US/docs/JavaScript/Reference/Global_Objects/Error"><code>Error</code></a> 对象作为拒绝理由。</p> + +<h2 id="方法概览">方法概览</h2> + +<table> + <tbody> + <tr> + <td><code>Promise <a href="https://developer.mozilla.org/zh-CN/docs/Mozilla/JavaScript_code_modules/Promise.jsm/Promise$edit#then()">then</a>([optional] <a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function" title="/en-US/docs/JavaScript/Reference/Global_Objects/Function">Function</a> onFulfill, </code><code>[optional] </code><code><a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function" title="/en-US/docs/JavaScript/Reference/Global_Objects/Function">Function</a> onReject</code><code>);</code></td> + </tr> + <tr> + <td><code>Promise <a href="https://developer.mozilla.org/zh-CN/docs/Mozilla/JavaScript_code_modules/Promise.jsm/Promise$edit#catch">catch</a>([optional] <a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function">Function</a> onReject);</code></td> + </tr> + </tbody> +</table> + +<h2 id="构造函数">构造函数</h2> + +<p>创建一个新的promise,初始化为等待状态,并提供解决函数的引用,用于改变其状态。</p> + +<pre><code>new Promise(executor);</code></pre> + +<h3 id="参数">参数</h3> + +<dl> + <dt><code>executor</code></dt> + <dd> + <p>该函数会马上被调用,它带有两个参数的函数对象:</p> + + <p> </p> + </dd> + <dd> + <pre><code>executor(resolve, reject);</code></pre> + + <p>构造函数直到执行完成才会返回。解决函数可以在任何时间被调用,在执行过程完成前后都可以,其目标是控制promise的最终状态。如果执行过程抛出异常,异常值会被传递到reject解决函数中。</p> + </dd> +</dl> + +<h3 id="解决函数">解决函数</h3> + +<h4 id="resolve()">resolve()</h4> + +<p>用特定值满足绑定的promise,或者把状态传递到一个已存在的promise。如果绑定的promise已经被解决(可能是一个值,也可能是一个rejection,或者是另一个promise),该方法不会做任何事。</p> + +<div class="note"> +<p><strong>备注:</strong> 调用该方法时,如果用一个pending状态的promise作为aValue参数,然后在该promise状态改变为fullfilled或者rejected前用另一个值再次调用,第二次调用将不会生效,因为这个绑定的promise已经被pending promise所解决了。</p> +</div> + +<pre><code>void resolve( + aValue +);</code></pre> + +<h6 id="参数_2">参数</h6> + +<dl> + <dt><code>aValue</code> 可选</dt> + <dd>如果这个值不是一个promise,包括 <code>undefined</code>, 它会变成绑定promise的实现值。如果这个值是promise,绑定promise会被传递的promise解决,并跟随所提供的promise的状态(包括任何未来的转变)。</dd> +</dl> + +<h4 id="reject()">reject()</h4> + +<p>用特定原因拒绝绑定的promise。如果promise已经被解决了,不管是值,拒绝,还是另一个promise,这个方法都不会做任何事。</p> + +<pre><code>void reject( + aReason +);</code></pre> + +<h6 id="参数_3">参数</h6> + +<dl> + <dt><code>aReason</code> 可选</dt> + <dd>绑定promise的拒绝原因。通常是一个 <a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Error">Error</a> 对象,就像在异常处理那样,尽管理由也可以是 <code>undefined。</code></dd> +</dl> + +<div class="note"> +<p><strong>备注:</strong> 该参数不应该是promise。要说明一个被拒绝的promise,应该让拒绝原因等于被拒绝promise自身,而非其拒绝原因。</p> +</div> + +<h2 id="方法">方法</h2> + +<h3 id="then()">then()</h3> + +<p><span style="line-height: 1.5;">一旦promise完成或被拒绝,就立即执行一个回调函数,并返回一个新的promise对象,新promise的状态取决于promise和传入的回调函数</span></p> + +<div>回调函数始终会在<code>then</code>返回值后被调用,即使promise早已完成或已被拒绝。也可对多次调用同一个promise的<code>then</code>方法。所有的回调函数会按照其注册的顺序被调用。</div> + +<p> </p> + +<div class="warning"> +<p><strong>警告</strong>: 如果 <code>onFulfill</code> 抛出异常,不会调用 <code>onReject</code> ,异常也不会被捕获和输出到控制台(你会看到一个promise chain失败错误),可以在返回的promise上注册一个错误处理函数,以处理在任一回调中出现的异常(使用 catch() 或者 then() ),来处理发生在任何一个注册回调函数的异常。</p> +</div> + +<p> </p> + +<div class="note"> +<p><strong>注意</strong>:当多次调用同一个promise的then方法,所有注册的回调函数独立执行。如,当在一个回调函数中出现异常时,不会影响后面回调函数的执行。回调函数的结果只会对其注册所使用的then方法返回的promise产生影响,每一次调用then方法返回的都是不同的promise对象。</p> +</div> + +<pre>Promise then( + Function onFulfill, + Function onReject +); +</pre> + +<h6 id="参数_4">参数</h6> + +<dl> + <dt><code>onFulfill</code> {{optional_inline()}}</dt> + <dd>当promise完成时,会调用该函数,并将完成值作为其唯一参数传入,该函数的输出会决定新的promise的状态。如果该参数不是函数(通常为<code>null</code>),则由then返回的新的promise的状态为已完成,且完成值与原promise相同</dd> + <dt><code>onReject</code> {{optional_inline()}}</dt> + <dd> + <p>当promise被拒绝时,会调用该函数,并将拒绝理由作为其唯一参数传入,且该函数的输出会决定新的promise的状态。如果该参数不是函数(通常为<code>undefined</code>),则由<code>then</code>返回的新的promise的状态为拒绝,且拒绝理由与原promise相同。</p> + </dd> +</dl> + +<h6 id="返回值">返回值</h6> + +<p>新的promise对象,初始状态为未完成,最终状态取决于回调函数的输出:</p> + +<ul> + <li> + <div>如果返回的不是promise,包括<code>undefined</code>,则新promise的状态为已完成,并将该返回值作为其完成值,即使原promises被拒绝</div> + </li> + <li> + <div><span style="line-height: 1.5;">如果抛出异常,则新的promise的状态为拒绝,并将该异常作为其拒绝理由,即使原promise已完成</span></div> + </li> + <li> + <div><span style="line-height: 1.5;">如果返回promise,则新promise的最终状态与回调函数返回的promise状态相同。</span></div> + </li> +</ul> + +<div> +<h3 id="catch()"><a name="catch">catch()</a></h3> + +<p>等价于调用<code>onFulfill参数为undefined的</code> <code>then()</code> 方法。如果你链式调用then( onFulfill ).catch( onReject ),onFulfill中抛出的异常会被捕捉并传递到onReject。</p> + +<pre><code>Promise catch( + Function onReject +);</code></pre> + +<p>等价于以下调用:</p> + +<pre><code>p.then(undefined, logError); +p.catch(logError);</code></pre> +</div> + +<div> </div> + +<h2 id="调试">调试</h2> + +<p>按照设计,在不调用 <code style="font-style: normal;"><a href="#then()" title="#then()">then()</a></code>的情况下,promise的即时状态和值不能通过代码同步检测到。</p> + +<p>为了有助于调试,只有当手动检查promise时,才能看到那些不能通过代码访问的特殊属性的信息(目前由于缺少复杂的语言或调试器的支持,属性名是随机生成的)。</p> + +<p>这些代码可访问和可审查的属性有:</p> + +<ul> + <li><code><strong><span>{</span>{private:status}}</strong></code>: 0代表未完成,1代表已完成,2代表拒绝。</li> + <li><code><strong><span>{</span>{private:value}}</strong></code>:完成值或拒绝理由,仅在promise已完成或已拒绝时有值。</li> + <li><code><strong><span>{</span>{private:handlers}}</strong></code>: 对象数组,这些对象保存了对回调函数的引用,仅在未完成状态下可用。</li> +</ul> + +<p style="text-align: center;"><img alt="Promise properties are visible in the debugger." src="https://mdn.mozillademos.org/files/6471/Promise-Debug-1.png" style="border-style: solid; border-width: 2px; height: 482px; margin-bottom: 15px; margin-top: 15px; width: 403px;"><img alt="Promise handlers can be watched from the Console." src="https://mdn.mozillademos.org/files/6473/Promise-Debug-2.png" style="border-style: solid; border-width: 2px; height: 161px; width: 977px;"></p> + +<h2 id="示例">示例</h2> + +<p id="如何抛出拒绝">请看 <a href="https://developer.mozilla.org/Mozilla/JavaScript_code_modules/Promise.jsm/Examples">示例</a> 页面.</p> + +<h2 id="异常处理和常见误区">异常处理和常见误区</h2> + +<p>promise应该报告未处理的错误,除非交给其他程序处理该错误。</p> + +<pre class="brush: js">// ###### WRONG: Silently drops any rejection notified by "OS.File.Exists". +OS.File.exists(path).then(exists => { if (exists) myRead(path); }); + +// ###### WRONG: Silently drops any exception raised by "myRead". +OS.File.exists(path).then(exists => { if (exists) myRead(path); }, Components.utils.reportError); + +// CORRECT (for example, might report the exception "myRead is not defined") +OS.File.exists(path).then(exists => { if (exists) myRead(path); }) + .catch(null, Components.utils.reportError); + +// CORRECT (the function returns a promise, and the caller will handle the rejection) +function myReadIfExists(path) +{ + return OS.File.exists(path).then(exists => { if (exists) myRead(path); }); +}</pre> + +<h2 id="参见">参见</h2> + +<ul> + <li><a href="/en-US/docs/Mozilla/JavaScript_code_modules/Promise.jsm" title="/en-US/docs/Mozilla/JavaScript_code_modules/Promise.jsm">Promise.jsm</a></li> + <li><a href="/en-US/docs/Mozilla/JavaScript_code_modules/Promise.jsm/Deferred" title="/en-US/docs/Mozilla/JavaScript_code_modules/Promise.jsm/Deferred">Deferred</a></li> + <li><a href="/en-US/docs/JavaScript_OS.File" title="/en-US/docs/JavaScript_OS.File">JavaScript OS.File</a></li> + <li><a href="http://kryogenix.org/days/2013/12/12/promises-promises">Promises, Promises</a>: a useful simple explanation by Stuart Langridge</li> + <li><a href="http://dom.spec.whatwg.org/#promises">WHATWG Living Standard</a></li> +</ul> |