blob: a81af18ffe0d69dd149312e5c1f06c1264d42f2f (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
---
title: Promise() 构造器
slug: Web/JavaScript/Reference/Global_Objects/Promise/Promise
translation_of: Web/JavaScript/Reference/Global_Objects/Promise/Promise
---
<div>{{JSRef}}</div>
<p><strong><code>Promise</code></strong> 构造器主要用于包装不支持promise(返回值不是<code>Promise</code>)的函数。</p>
<div>{{EmbedInteractiveExample("pages/js/promise-constructor.html")}}</div>
<h2 id="语法">语法</h2>
<pre class="syntaxbox">new Promise(<var>executor</var>)</pre>
<h3 id="参数">参数</h3>
<dl>
<dt><code>executor</code></dt>
<dd>
<p>该函数将在构造这个新<code>Promise</code>对象过程中,被构造函数执行。该<code>executor</code>是一段将输出与promise联系起来的自定义代码。<code>executor</code>的函数签名应为:</p>
<pre class="brush: js;">function(resolutionFunc, rejectionFunc){
// 通常是一些异步操作
}
</pre>
<p>
<code>resolutionFunc</code>与<code>rejectionFunc</code>也是函数,可以使用任何名字。这两个函数的签名很简单:接受任何类型的单个参数。
</p>
<pre class="brush: js;">
resolutionFunc(value) // 当被敲定时调用
rejectionFunc(reason) // 当被拒绝时调用
</pre>
<p>
当该promise动态插入<a href="/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise#promise%E7%9A%84%E9%93%BE%E5%BC%8F%E8%B0%83%E7%94%A8">promise链</a>的情况下,该<code>resolutionFunc</code>的<code>value</code>参数可能是另一个promise对象。
</p>
<p>
关于<code>executor</code>,需理解以下几点:
</p>
<ul>
<li>该<code>executor</code>的返回值将被忽略。</li>
<li>如果在该<code>executor</code>中抛出一个错误,该promise将被拒绝。</li>
</ul>
<p>
因此,<code>executor</code>的代码生效的原理如下:
</p>
<ul>
<li>在构造函数生成新<code>Promise</code>对象时,构造函数也生成了一对相关的函数<code>resolutionFunc</code>与<code>rejectionFunc</code>。他们被绑定在了<code>Promise</code>对象上。</li>
<li><code>executor</code>内的代码有机会执行一些操作,然后通过分别调用<code>resolutionFunc</code>或者<code>rejectionFunc</code>,反应这些操作的结果(如果这些结果不是另一个<code>Promise</code>对象的话),要么为已敲定(resolved),要么为已拒绝(rejected)。</li>
<li>换句话说,<code>executor</code>中的代码通过<code>resolutionFunc</code>或<code>rejectionFunc</code>产生的副作用进行通信。这里的副作用是指<code>Promise</code>对象变成已敲定(resolved),要么为已拒绝(rejected)。</li>
</ul>
<p>
综上所述,对典型流程进行总结:
</p>
<ol>
<li><code>executor</code>内的操作是异步的,并且提供一个回调(callback)。</li>
<li>该回调在<code>executor</code>内定义。</li>
<li>该回调通过调用<code>resolutionFunc</code>终止。</li>
<li><code>resolutionFunc</code>的调用包含一个<code>value</code>参数。</li>
<li>该<code>value</code>被返回给绑定的<code>Promise</code>对象上。</li>
<li>该<code>Promise</code>对象(异步地)调用任何相关的<code>.then(handleResolved)</code>。</li>
<li><code>.then(handleResolved)</code>收到的<code>value</code>作为入参被传递给了<code>handleResolved</code>的调用。(参见<a href="/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise#promise%E7%9A%84%E9%93%BE%E5%BC%8F%E8%B0%83%E7%94%A8">Promise的链式调用</a>)</li>
</ol>
</dd>
</dl>
<h3 id="返回值">返回值</h3>
<div>
<p>
当通过<code>new</code>调用时,<code>Promise</code>构造函数返回一个promise对象。当<code>resolutionFunc</code>或者<code>rejectionFunc</code>被调用时,该promise对象将会“被敲定”。注意,如果您调用<code>resolutionFunc</code>或者<code>rejectionFunc</code>时将另一个Promise对象作为参数,您可以称其“被敲定(resolved)”,但仍不能称其“被解决(settled)”。
</p>
</div>
<h2 id="例子">例子</h2>
<p>我们通过<code>new</code>关键字和<code>Promise</code>构造器创建它的对象。这个构造器接受一个名为"executor function"的函数。这个函数应当接受两个函数参数。当异步任务成功时,第一个函数(<code>resolve</code>)将被调用,并返回一个值代表成功。当其失败时,第二个函数(<code>reject</code>)将被调用,并返回失败原因(失败原因通常是一个error对象)。</p>
<pre class="brush: js;">const myFirstPromise = new Promise((resolve, reject) => {
// do something asynchronous which eventually calls either:
//
// resolve(someValue) // fulfilled
// or
// reject("failure reason") // rejected
});
</pre>
<p>为了提供一个拥有promise功能的函数,简单的返回一个promise即可:</p>
<pre class="brush: js;">function myAsyncFunction(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.open("GET", url)
xhr.onload = () => resolve(xhr.responseText)
xhr.onerror = () => reject(xhr.statusText)
xhr.send()
});
}</pre>
<h2 id="说明">说明</h2>
<table class="standard-table">
<tbody>
<tr>
<th scope="col">Specification</th>
</tr>
<tr>
<td>{{SpecName('ESDraft', '#sec-promise-constructor', 'Promise constructor')}}</td>
</tr>
</tbody>
</table>
<h2 id="浏览器兼容性">浏览器兼容性</h2>
<p>{{Compat("javascript.builtins.Promise.Promise")}}</p>
<h2 id="See_also">See also</h2>
<ul>
<li><a href="/en-US/docs/Web/JavaScript/Guide/Using_promises">Using Promises</a></li>
</ul>
|