Promise
Baseline
Widely available
*
This feature is well established and works across many devices and browser versions. Itâs been available across browsers since 2015å¹´7æ.
* Some parts of this feature may have varying levels of support.
Promise ç©ä»¶ä»£è¡¨ä¸åå³å°å®æãæå¤±æçé忥æä½ï¼ä»¥å宿ç¢ççå¼ã
åè¨»ï¼æ¤æ¢ç®çºä»ç´¹ Promise 建æ§å¼ãè¦çè§£ Promise ç¸éä½¿ç¨æ¹å¼ï¼è«å åèä½¿ç¨ PromiseãPromise 建æ§å¼ä¸»è¦ç¨æ¼å è£¹å°æªæ¯æ´ Promise çå½å¼ã
å試ä¸ä¸
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("foo");
}, 300);
});
promise1.then((value) => {
console.log(value);
// Expected output: "foo"
});
console.log(promise1);
// Expected output: [object Promise]
èªæ³
new Promise( /* executor */ function(resolve, reject) { ... } );
忏
- executor
-
çºä¸åä¾åºæ¥æ¶å ©å忏çå½å¼ï¼
resolveårejectï¼å¯¦ç¾åæçµåå¼å½å¼ï¼ãå¨ Promise 實ä½ä¸ï¼executorå½å¼å¨å³å ¥åæ¸resolveèreject徿ç«å»å·è¡ï¼executorå½å¼æå¨Promise建æ§å¼åå³ Promise ç©ä»¶å被å·è¡ï¼ãresolveèrejectå½å¼ï¼æå¨è¢«åå¥å¼å«æï¼åå¥å·è¡ä¹ãé常 executor å½å¼æç¼èµ·ä¸äºé忥æä½ãæ¥èï¼æå宿å¾å·è¡resolve以宿 promiseï¼æå¦ææé¯èª¤ï¼å·è¡rejectsã 妿 executor å½å¼å¨å·è¡ä¸æåºé¯èª¤ï¼promise æè¢«æçµï¼rejectedï¼ï¼åå³å¼ä¹å°è¢«å¿½ç¥ã
æè¿°
Promise æä»£çä¸åå»ºç«æï¼ä¸ç¨é å
å¾ç¥çå¼ãå®ä½¿ä½ è½å¤ 繫çµï¼associateï¼èç¼åé忥æä½å¾ï¼æçµçæåå¼ï¼success valueï¼æå¤±æè¨æ¯ï¼failure reasonï¼çèçå½å¼ï¼handlersï¼ãéè®éåæ¥æ¹æ³åå³å¼çæ¹å¼å¾ååæ¥æ¹æ³ï¼ä½ä¸æ¯å峿çµçµæï¼éåæ¥æ¹æ³åå³ä¸å promise ç©ä»¶ä½çºæªä¾ææéé»çå¼ã
ä¸å Promise ç©ä»¶èæ¼ä»¥ä¸å¹¾ç¨®çæ
ï¼
- æ±ç½®ï¼pendingï¼ï¼åå§çæ ï¼ä¸æ¯ fulfilled è rejectedã
- 實ç¾ï¼fulfilledï¼ï¼è¡¨ç¤ºæä½æåå°å®æã
- æçµï¼rejectedï¼ï¼è¡¨ç¤ºæä½å¤±æäºã
ä¸åèæ¼æ±ç½®çæ
ç promise è½ä»¥ä¸åå¼è¢«å¯¦ç¾ï¼fulfilledï¼ï¼ææ¯ä»¥ä¸ååå æé¯èª¤è被æçµï¼rejectedï¼ãç¶ä¸è¿°ä»»ä¸çæ
è½æç¼çæï¼é£äºéé then æ¹æ³æç¹«çµï¼associatedï¼çèçå½å¼åéå°±æä¾åºè¢«èª¿ç¨ãï¼è¥ä¸å promise å·²è¢«å¯¦ç¾ææçµï¼ç¹«çµï¼attachedï¼æ¼å®çèçå½å¼å°ç«å³è¢«å¼å«ï¼å æ¤å®æé忥æä½è繫çµèçå½å¼ä¹éä¸åå¨ç«¶çæ¢ä»¶ï¼race conditionï¼ãï¼
ç±æ¼ Promise.prototype.then() 以å Promise.prototype.catch() æ¹æ³é½åå³ promiseï¼å®åå¯ä»¥è¢«ä¸²æ¥ã
å註ï¼è¨±å¤å
¶ä»èªè¨æææ©å¶ç¨ä¾æ°æ§æ±å¼ï¼lazy evaluationï¼åå»¶é²ï¼deferringï¼éç®ï¼å®åä¹è¢«ç¨±ä½ãpromisesã â e.g. Scheme. ç¶èå¨ JavaScript ä¸ Promises 代表é£äºï¼å·²ç¶ï¼ç¼çä¸ï¼happeningï¼çç¨åºï¼å®åå¯ä»¥ç¹«çµåå¼å½å¼ãè¥ä½ è¦æ¾çæ¯æ°æ§æ±å¼è¡¨ç¤ºå¼ï¼èæ
®ä¸å¸¶åæ¸ç arrow functionï¼f = () => expression ä¾å»ºç«æ°æ§æ±å¼è¡¨ç¤ºå¼ï¼ä¸¦éé f() é²è¡æ±å¼.
å註ï¼ä¸åè¢«å¯¦ç¾ææçµï¼ä½ä¸èæ¼ pending ç promise 被稱ä½è¢«è§£æ±ºï¼settledï¼ãä½ ä¹æè¦å°ä½¿ç¨è§£æ±ºï¼resolvedï¼ä¸è©ä¾æè¿° promises â é代表 promises 被實ç¾ï¼fulfilledï¼äºãStates and fates éç¯æç« å å«äºæ´å¤ promises çå°æåè©ã
屬æ§
Promise.length-
é·åº¦å±¬æ§ï¼å¼åºå®çº
1ã(建æ§å¼åæ¸æ¸ç®). Promise.prototype-
Promise建æ§å¼çååï¼prototypeï¼.
æ¹æ³
Promise.all(iterable)-
åå³ä¸å promiseï¼ç¶å¨å¼æ¸ iterable 䏿æ promises é½è¢«å¯¦ç¾æè¢«å¯¦ç¾ï¼æå¨å¼æ¸ iterable 䏿ä¸å promise 被æçµæç«å»è¢«æçµãè¥åå³ç promise 被實ç¾ï¼å®å°ä»¥ä¸å實ç¾å¼çé£å被實ç¾ï¼å ¶é åºè iterable ä¸ç promises ç¸åãè¥åå³ç promise 被æçµï¼å®å°ä»¥å¤±æè¨æ¯è¢«æçµï¼æ¤è¨æ¯ä¾èªç¬¬ä¸åå¨ iterable ä¸è¢«æçµç promiseãéåæ¹æ³å¨èéè¨±å¤ promises ççµææå¾ææã
Promise.race(iterable)-
åå³ä¸åè¢«å¯¦ç¾ææçµç promiseï¼ç¶ iterable 䏿ä¸å promise è¢«å¯¦ç¾ææçµæã
Promise.reject(reason)-
åå³ä¸å以失æè¨æ¯æçµç
promiseã Promise.resolve(value)-
åå³ä¸å以 value 實ç¾ç
promiseãè¥è©²å¼çº thenable (i.e. å ·æthenæ¹æ³)ï¼åå³ç promise å°è·é¨ï¼followï¼ä¹ï¼æ¡ç¨å¥¹çæçµçæ ï¼ å¨å ¶ä»æ å½¢åå³ç promise å°ä»¥ value 被實ç¾ãä¸è¬ä¾èªªï¼ç¶ä½ ä¸ç¥é value æ¯å¦çº promiseï¼ä½¿ç¨Promise.resolve(value)ï¼å°åå³å¼ä»¥ promise ä½èçã
Promise åå
>
屬æ§
Promise.prototype[Symbol.toStringTag]-
The initial value of the
Symbol.toStringTagproperty is the string"Promise". This property is used inObject.prototype.toString().
æ¹æ³
See the Microtask guide to learn more about how these methods use the Microtask queue and services.
Promise.prototype.catch()-
Appends a rejection handler callback to the promise, and returns a new promise resolving to the return value of the callback if it is called, or to its original fulfillment value if the promise is instead fulfilled.
Promise.prototype.then()-
Appends fulfillment and rejection handlers to the promise, and returns a new promise resolving to the return value of the called handler, or to its original settled value if the promise was not handled (i.e. if the relevant handler
onFulfilledoronRejectedis not a function). Promise.prototype.finally()-
Appends a handler to the promise, and returns a new promise that is resolved when the original promise is resolved. The handler is called when the promise is settled, whether fulfilled or rejected.
å»ºç« Promise
ä¸å Promise ç©ä»¶éé new åå
¶å»ºæ§å¼å»ºç«ãéå建æ§å¼æ¥æ¶ä¸åå«ä½ãå·è¡å¨å½å¼ï¼executor functionï¼ãç弿¸ãæ¤å½å¼æ¥æ¶å
©åå½å¼ä½çºå¼æ¸ã第ä¸åå½å¼ï¼resolveï¼å¨é忥使¥æå宿æï¼ä»¥è©²ä½æ¥ä¹çµæå¼è¢«å¼å«ã第äºåå½å¼ï¼rejectï¼å¨ä½æ¥å¤±ææï¼ä»¥å¤±æè¨æ¯ï¼é常æ¯ä¸å error objectï¼è¢«å¼å«ã
const myFirstPromise = new Promise((resolve, reject) => {
// å·è¡ä¸äºé忥使¥ï¼æçµå¼å«:
//
// resolve(someValue); // 實ç¾
// æ
// reject("failure reason"); // æçµ
});
è¦æä¾ä¸åå½å¼ promise åè½ï¼è®å®åå³ä¸å promise å³å¯ï¼
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();
});
}
ç¯ä¾
>å ¥éç¯ä¾
let myFirstPromise = new Promise((resolve, reject) => {
// ç¶é忥使¥æåæï¼å¼å« resolve(...),è失ææåå¼å« reject(...)ã
// å¨éåä¾åä¸ï¼ä½¿ç¨ setTimeout(...) 便¨¡æ¬é忥ç¨å¼ç¢¼ã
// å¨å¯¦åä¸ï¼ä½ å°å¯è½ä½¿ç¨åæ¯ XHR æè
ä¸å HTML5 API.
setTimeout(function () {
resolve("Success!"); // Yayï¼é常é å©ï¼
}, 250);
});
myFirstPromise.then((successMessage) => {
// successMessage æ¯ä»»ä½ä½ ç±ä¸æ¹ resolve(...) å³å
¥çæ±è¥¿ã
// 卿¤å
ä½çºæåè¨æ¯ï¼ä½æ¯å®ä¸ä¸å®æ¯å串ã
console.log("Yay! " + successMessage);
});
é²éç¯ä¾
<button id="btn">Make a promise!</button>
<div id="log"></div>
éåå°ç¯ä¾æ¼ç¤ºäº Promise çé使©å¶ãæ¯ç¶ <button> è¢«é»ææï¼testPromise() æ¹æ³è¢«å¼å«ãæ¯æ¬¡é»æå°éé window.setTimeout() 建ç«ä¸åå°å¨ 1-3 ç§å
§é¨æ©å°è¢«å¯¦ç¾ç promiseï¼ä¾ promise è¨æ¸ï¼ä¸åå¾ 1 éå§çæ¸å¼ï¼ã建æ§å¼ Promise() 被ç¨ä¾å»ºç« promiseã
promise ç實ç¾å¼å®ç´å°ç¶ç±ä¸å實ç¾åå¼å½å¼ p1.then() 被å°åºãä¸ä»¥ä¸äºæåç´éä¾å±ç¾æ¹æ³ä¸åæ¥çèé忥èç promise çé¨åæ¯å¦ä½åé¢å½¼æ¤ã
"use strict";
var promiseCount = 0;
function testPromise() {
let thisPromiseCount = ++promiseCount;
let log = document.getElementById("log");
log.insertAdjacentHTML(
"beforeend",
thisPromiseCount + ") Started (<small>Sync code started</small>)<br/>",
);
// 建ç«ä¸åæ°ç promiseï¼æ¤ promise æ¿è«¾ä¸åæ¸å¼è¨æ¸, ç± 1 éå§ï¼çå¾
ç´ 2 ç§ï¼
let p1 = new Promise(
// éå解決å¨å½æ¸ï¼resolver functionï¼å¼å«å¯¦ç¾æ
// æçµ promiseã
(resolve, reject) => {
log.insertAdjacentHTML(
"beforeend",
thisPromiseCount +
") Promise started (<small>Async code started</small>)<br/>",
);
// 卿¤ä¾åå®ç´ç¨ä¾ç¢çéåæ¥ç¹æ§ã
window.setTimeout(
function () {
// 實ç¾éå promise!
resolve(thisPromiseCount);
},
Math.random() * 2000 + 1000,
);
},
);
// æ¥èééå¼å« then() 便±ºå® promise é²å
¥ resolved æï¼è¦éé then() åä»éº¼ï¼
// ææ¯é²å
¥ rejected æï¼è¦éé catch() æ¹æ³è¦åä»éº¼ã
p1.then(
// å°åºå¯¦ç¾å¼ï¼fulfillment valueï¼
function (val) {
log.insertAdjacentHTML(
"beforeend",
val + ") Promise fulfilled (<small>Async code terminated</small>)<br/>",
);
},
).catch(
// å°åºå¤±æè¨æ¯ï¼rejection reasonï¼
(reason) => {
console.log("Handle rejected promise (" + reason + ") here.");
},
);
log.insertAdjacentHTML(
"beforeend",
thisPromiseCount +
") Promise made (<small>Sync code terminated</small>)<br/>",
);
}
è¯è¨»ï¼resolver function å³ executor functionã
if ("Promise" in window) {
let btn = document.getElementById("btn");
btn.addEventListener("click", testPromise);
} else {
log = document.getElementById("log");
log.innerHTML =
"Live example not available as your browser doesn't support the <code>Promise<code> interface.";
}
éåç¯ä¾å¾é»ææééå§ãä½ çç覽å¨éè¦æ¯æ´ Promiseãå¨çæéå §é»ææéè¨±å¤æ¬¡ï¼ä½ çè³å°çå°ä¸åç promises ä¸åæ¥ä¸åå°è¢«å¯¦ç¾ã
ä½¿ç¨ XHR è¼å ¥åç
å¦ä¸åä½¿ç¨ Promise and XMLHttpRequest ä¾è¼å
¥åççç°¡å®ä¾åå¯ä»¥å¨ MDN GitHub js-examples å²å庫æ¾å°ã ä½ ä¹å¯ä»¥see it in actionãæ¯åæ¥é©é½é以註解ï¼è®ä½ è½éæ¥éµé¨ Promise è XHR æ¶æ§ã
è¦ç¯
| Specification |
|---|
| ECMAScript® 2027 Language Specification> # sec-promise-objects> |
ç覽å¨ç¸å®¹æ§
åè¦
core-jsä¸Promiseç polyfill- ä½¿ç¨ Promise æå
- Promises/A+ è¦ç¯
- JavaScript Promiseï¼ç°¡ä»ï¼web.devï¼2013ï¼
- åå¼ãPromise ååç¨ï¼JavaScript ä¸çé忥ç¨å¼è¨è¨æ¨¡å¼ï¼ä¾èª Domenic Denicola çå¹»ççï¼2011ï¼