Promise

翻譯不完整。請協助 翻譯此英文文件

Promise 物件代表了最終將會完成(或失敗)的一個非同步操作,以及其產生的值。

此條目為介紹 Promise 建構式。要瞭解 Promise 相關使用方式,請先參考使用 Promise。Promise 建構式主要用於包裹尚未支援 Promise 的函式。

語法

new Promise( /* executor */ function(resolve, reject) { ... } );

參數

executor
一個接收參數 resolvereject 的執行函式。此 executor 函式會在建立 Promise 物件時自動傳入參數 resolve(解決回呼函式)、reject(拒絕回呼函式)並立刻被執行(executor 函式會在 Promise 建構式回傳 Promise 物件前被執行),resolvereject 回呼函式可分別在解決或拒絕時呼叫執行。executor 函式一般用來執行一些非同步操作,操作完成後可以藉由呼叫 resolvereject 回呼函式來決定建構式所回傳 Promise 物件的狀態,並以此約定將特定的值傳入解決或是拒絕後的流程中。
如果有錯誤在 executor 函式執行過程中被拋出,Promise 物件的狀態將會是 rejected,且不會將約定之特定值傳入之後的流程。

描述

Promise 是一個操作值的代理物件,此操作值在 Promise 物件被建立時並不一定有被定義。Promise 物件允許你預先為一個非同步操作結束後的成功回傳值或失敗訊息繫結其處理函式,這使得非同步方法可以像同步方法一樣立即回傳一個值:非同步方法會回傳一個 promise 物件來間接提供真正的回傳值供未來某個時間點使用,而不是直接、立即的回傳最終結果值。

Promise 物件有以下幾種狀態:

  • pending:等待中,為初始之狀態,即不是 fulfilled 也不是 rejected。
  • fulfilled:已實現,表示操作成功完成。
  • rejected:已拒絕,表示操作失敗。

一個處於 pending 的 promise 物件可以轉變成 fulfilled 狀態並帶有特定值,或是轉為 rejected 狀態並帶有錯誤訊息。當上述任一狀態轉換發生時,使用 Promise 物件 then 方法所繫結的處理函式就會依序被調用。(若在綁定處理函式時,Promise 物件狀態已是 fulfilled 或 rejected,則其對應的處理函式會立即被呼叫,所以非同步操作是否完成與其所繫結的處理函式之間並不存在競賽條件(race condition)。)

由於 Promise.prototype.then() 以及 Promise.prototype.catch() 方法會回傳 promise 物件,因此它們可以被鏈式調用。

Not to be confused with: Several other languages have mechanisms for lazy evaluation and deferring a computation, which they also call “promises” — e.g. Scheme. Promises in JavaScript represent processes which are already happening, which can be chained with callback functions. If you are looking to lazily evaluate an expression, consider the arrow function with no arguments: f = () => expression to create the lazily-evaluated expression, and f() to evaluate.

Note: A promise is said to be settled if it is either fulfilled or rejected, but not pending. You will also hear the term resolved used with promises — this means that the promise is fulfilled. Domenic Denicola's States and fates contains more details about promise terminology.

屬性

Promise.length
Length property whose value is always 1 (number of constructor arguments).
Promise.prototype
Represents the prototype for the Promise constructor.

方法

Promise.all(iterable)
Returns a promise that either fulfills when all of the promises in the iterable argument have fulfilled or rejects as soon as one of the promises in the iterable argument rejects. If the returned promise fulfills, it is fulfilled with an array of the values from the fulfilled promises in the same order as defined in the iterable. If the returned promise rejects, it is rejected with the reason from the first promise in the iterable that rejected. This method can be useful for aggregating results of multiple promises.
Promise.race(iterable)
Returns a promise that fulfills or rejects as soon as one of the promises in the iterable fulfills or rejects, with the value or reason from that promise.
Promise.reject(reason)
Returns a Promise object that is rejected with the given reason.
Promise.resolve(value)
Returns a Promise object that is resolved with the given value. If the value is a thenable (i.e. has a then method), the returned promise will "follow" that thenable, adopting its eventual state; otherwise the returned promise will be fulfilled with the value. Generally, if you don't know if a value is a promise or not, Promise.resolve(value) it instead and work with the return value as a promise.

Promise 原型

屬性

Promise.prototype.constructor
Returns the function that created an instance's prototype. This is the Promise function by default.

方法

Promise.prototype.catch(onRejected)
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(onFulfilled, onRejected)
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 onFulfilled or onRejected is not a function).

Creating a Promise

A Promise object is created using the new keyword and its constructor. This constructor takes as its argument a function, called the "executor function". This function should take two functions as parameters. The first of these functions (resolve) is called when the asynchronous task completes successfully and returns the results of the task as a value. The second (reject) is called when the task fails, and returns the reason for failure, which is typically an error object.

const myFirstPromise = new Promise((resolve, reject) => {
  // do something asynchronous which eventually calls either:
  //
  //   resolve(someValue); // fulfilled
  // or
  //   reject("failure reason"); // rejected
});

To provide a function with promise functionality, simply have it return a 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();
  });
};

範例

Basic Example

let myFirstPromise = new Promise((resolve, reject) => {
  // We call resolve(...) when what we were doing made async successful, and reject(...) when it failed.
  // In this example, we use setTimeout(...) to simulate async code. 
  // In reality, you will probably be using something like XHR or an HTML5 API.
  setTimeout(function(){
    resolve("Success!"); // Yay! Everything went well!
  }, 250);
});

myFirstPromise.then((successMessage) => {
  // successMessage is whatever we passed in the resolve(...) function above.
  // It doesn't have to be a string, but if it is only a succeed message, it probably will be.
  console.log("Yay! " + successMessage);
});

Advanced Example

This small example shows the mechanism of a Promise. The testPromise() method is called each time the <button> is clicked. It creates a promise that will be fulfilled, using window.setTimeout(), to the promise count (number starting from 1) every 1-3 seconds, at random. The Promise() constructor is used to create the promise.

The fulfillment of the promise is simply logged, via a fulfill callback set using p1.then(). A few logs show how the synchronous part of the method is decoupled from the asynchronous completion of the 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/>');

    // We make a new promise: we promise a numeric count of this promise, starting from 1 (after waiting 3s)
    let p1 = new Promise(
        // The resolver function is called with the ability to resolve or
        // reject the promise
       (resolve, reject) => {
            log.insertAdjacentHTML('beforeend', thisPromiseCount +
                ') Promise started (<small>Async code started</small>)<br/>');
            // This is only an example to create asynchronism
            window.setTimeout(
                function() {
                    // We fulfill the promise !
                    resolve(thisPromiseCount);
                }, Math.random() * 2000 + 1000);
        }
    );

    // We define what to do when the promise is resolved/rejected with the then() call,
    // and the catch() method defines what to do if the promise is rejected.
    p1.then(
        // Log the fulfillment value
        function(val) {
            log.insertAdjacentHTML('beforeend', val +
                ') Promise fulfilled (<small>Async code terminated</small>)<br/>');
        })
    .catch(
        // Log the rejection reason
       (reason) => {
            console.log('Handle rejected promise ('+reason+') here.');
        });

    log.insertAdjacentHTML('beforeend', thisPromiseCount +
        ') Promise made (<small>Sync code terminated</small>)<br/>');
}

This example is started by clicking the button. You need a browser that supports Promise. By clicking the button several times in a short amount of time, you'll even see the different promises being fulfilled one after another.

Loading an image with XHR

Another simple example using Promise and XMLHttpRequest to load an image is available at the MDN GitHub js-examples repository. You can also see it in action. Each step is commented and allows you to follow the Promise and XHR architecture closely.

規範

Specification Status Comment
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'Promise' in that specification.
Standard Initial definition in an ECMA standard.
ECMAScript Latest Draft (ECMA-262)
The definition of 'Promise' in that specification.
Draft

瀏覽器相容性

FeatureChromeEdgeFirefoxInternet ExplorerOperaSafari
Basic Support32.0(Yes)29.01No197.13
FeatureAndroidChrome for AndroidEdge mobileFirefox for AndroidIE mobileOpera AndroidiOS Safari
Basic Support4.4.432.0(Yes)291No(Yes)8.03

1. Constructor requires a new operator since version 37.

2. Constructor requires a new operator since version 4.

3. Constructor requires a new operator since version 10.

參見

文件標籤與貢獻者

 此頁面的貢獻者: jackblackevo
 最近更新: jackblackevo,