Heim  >  Artikel  >  Web-Frontend  >  Die Verwendung von Promise in JavaScript

Die Verwendung von Promise in JavaScript

高洛峰
高洛峰Original
2018-05-15 17:35:361279Durchsuche

Promise ist eine Funktion in ES6, die die Handhabung von Rückruffunktionen für asynchrone Aufgaben standardisiert. Ihre Funktion ähnelt der von jQuery. Vereinfacht ausgedrückt werden unterschiedliche Rückruffunktionen über unterschiedliche Zustände des Versprechenobjekts aufgerufen. Derzeit werden IE8 und niedriger nicht unterstützt, andere Browser jedoch schon.

Der Status des Versprechenobjekts ändert sich nicht, nachdem es von „Ausstehend“ in „Gelöst“ oder „Abgelehnt“ konvertiert wurde.

Verwendungsschritte:

var promise = new Promise(function(resolve, reject) {

 // 异步任务,通过调用resolve(value) 或 reject(error),以改变promise对象的状态;改变状态的方法只能在此调用。

//promise状态改变后,会调用对应的回调方法

});

promise.then(function(value){//resolve时的回调函数,参数由异步的函数传进来})

.catch(function(error){//发生异常时或明确reject()时的回调函数})

Spezifische Verwendung:

function getURL(URL) {           //因为promise创建时即执行,所以用工厂函数封装promise对象
  return new Promise(function (resolve, reject) {
    var req = new XMLHttpRequest();
    req.open('GET', URL, true);
    req.onload = function () {
      if (req.status === 200) {
        resolve(req.responseText);
      } else {
        reject(new Error(req.statusText));
      }
    };
    req.onerror = function () {
      reject(new Error(req.statusText));
    };
    req.send();
  });
}
// 运行示例
var URL = "http://httpbin.org/get";
getURL(URL).then(function onFulfilled(value){
  console.log(value);
}).catch(function onRejected(error){
  console.error(error);
})

Der Rückruf von Promise ist nur asynchron, selbst der Rückruf einer synchronen Aufgabe wird asynchron ausgeführt.

var promise = new Promise(function (resolve){
  console.log("inner promise");         // 执行1:同步任务先执行
  resolve(‘callBack');
});
promise.then(function(value){
  console.log(value);              // 执行3:虽然注册时状态为resolved,但回调仍是异步的;
});
console.log("outer promise");          // 执行2:同步代码先执行

Promise-Methodenkette

Die von der Then-Methode registrierten Rückrufe werden nacheinander aufgerufen und Parameter werden zwischen den einzelnen Then-Methoden über den Rückgabewert übergeben. Ausnahmen im Callback führen jedoch dazu, dass der Then-Callback übersprungen wird, der Catch-Callback direkt aufgerufen wird und dann die verbleibenden Then-Callbacks aufgerufen werden. In then(onFulfilled, onRejected) wird die onFulfilled-Ausnahme nicht von ihrem eigenen onRejected abgefangen, daher wird „catch“ zuerst verwendet.

Promise .then(taskA) .then(taskB) .catch(onRejected) .then(finalTask);

taskA löst eine Ausnahme aus, taskB wird übersprungen und finalTask ​​bleibt bestehen aufgerufen, weil Der Status des von Catch zurückgegebenen Versprechensobjekts wird aufgelöst.

Drei Werte können in der then-Methode zurückgegeben werden

1. Geben Sie ein weiteres Promise-Objekt zurück. Die nächste then-Methode wählt die Rückruffunktion onFullfilled/onRejected aus, die entsprechend ihrem Status ausgeführt werden soll werden immer noch durch die Auflösung des neuen Versprechens bestimmt.

2 Die nächste Methode erbt den Status des aktuellen Versprechens und wird sofort ausgeführt Die zu beendende asynchrone Aufgabe ist der Rückgabewert der vorherigen. Wenn nicht, wird standardmäßig undefiniert zurückgegeben.

3 ');

dann wird nicht nur eine Rückruffunktion registriert, sondern auch der Rückgabewert der Rückruffunktion transformiert, wodurch ein neues Versprechensobjekt erstellt und zurückgegeben wird. Tatsächlich arbeitet Promise nicht mit demselben Promise-Objekt in der Methodenkette.

var aPromise = new Promise(function (resolve) {
  resolve(100);
});
var thenPromise = aPromise.then(function (value) {
  console.log(value);
});
var catchPromise = thenPromise.catch(function (error) {
  console.error(error);
});
console.log(aPromise !== thenPromise); // => true
console.log(thenPromise !== catchPromise);// => true

Statische Methode Promise.all(), mehrere asynchrone Aufgaben gleichzeitig ausführen. Die nachfolgende Verarbeitung wird erst fortgesetzt, wenn alle empfangenen Versprechensobjekte „Erfüllt“ oder „Abgelehnt“ werden.

Promise.all([promiseA, promiseB]).then(function(results){//results是个数组,元素值和前面promises对象对应});

// 由promise对象组成的数组会同时执行,而不是一个一个顺序执行,开始时间基本相同。
function timerPromisefy(delay) {
  console.log('开始时间:”'+Date.now()) 
  return new Promise(function (resolve) {
    setTimeout(function () {
      resolve(delay);
    }, delay);
  });
}
var startDate = Date.now();
Promise.all([
  timerPromisefy(100),    //promise用工厂形式包装一下
  timerPromisefy(200),
  timerPromisefy(300),
  timerPromisefy(400)
]).then(function (values) {
  console.log(values);  // [100,200,300,400]
});

werden nicht gleichzeitig, sondern nacheinander ausgeführt

//promise factories返回promise对象,只有当前异步任务结束时才执行下一个then
function sequentialize(promiseFactories) {
  var chain = Promise.resolve();
  promiseFactories.forEach(function (promiseFactory) {
    chain = chain.then(promiseFactory);
  });
  return chain;
}

Promise.race() ähnelt all(), jedoch nur race() Zum Betreten ist ein Promise-Objekt erforderlich. Wenn es sich im Status „FulFilled“ oder „Rejected“ befindet, wird die entsprechende Rückruffunktion ausgeführt. Nachdem jedoch das erste Versprechenobjekt erfüllt wurde, hat dies keinen Einfluss auf die weitere Ausführung anderer Versprechenobjekte.

//沿用Promise.all()的例子
Promise.race([
  timerPromisefy(1),
  timerPromisefy(32),
  timerPromisefy(64),
  timerPromisefy(128)
]).then(function (value) {
  console.log(values);  // [1]
});

Die wunderbare Verwendung von Promise.race() als Timer

Promise.race([
  new Promise(function (resolve, reject) {
    setTimeout(reject, 5000);     // timeout after 5 secs
  }),
  doSomethingThatMayTakeAwhile()
]);

Ändern Sie den Promise-Status in then

Weil es in then nur Wertparameter gibt Rückruf, nein Die Methode zum Ändern des Status (kann nur in der asynchronen Aufgabe des Konstruktors verwendet werden. Wenn Sie den Status des an den nächsten übergebenen Promise-Objekts ändern möchten, können Sie nur ein neues Promise-Objekt erstellen und bestimmen). ob der Status in der asynchronen Aufgabe geändert werden soll. Schließlich wird die Rückgabe an den nächsten then/catch übergeben.

var promise = Promise.resolve(‘xxx');//创建promise对象的简介方法
promise.then(function (value) {
  var pms=new Promise(function(resolve,reject){
    setTimeout(function () {
      // 在此可以判断是否改变状态reject/resolve
      Reject(‘args');
    }, 1000);
  })
  return pms;  //该promise对象可以具有新状态,下一个then/catch需要等异步结束才会执行回调;如果返回普通值/undefined,之后的then/catch会立即执行
}).catch(function (error) {
  // 被reject时调用
  console.log(error)
});

Erhalten Sie die Ergebnisse von zwei Versprechen

//方法1:通过在外层的变量传递
var user;
getUserByName('nolan').then(function (result) {
  user = result;
  return getUserAccountById(user.id);
}).then(function (userAccount) {
  //可以访问user和userAccount
});

//方法2:后一个then方法提到前一个回调中
getUserByName('nolan').then(function (user) {
  return getUserAccountById(user.id).then(function (userAccount) {
    //可以访问user和userAccount
  });
});

Achten Sie auf die Gesamtstruktur, wenn Sie Versprechen verwenden

Angenommen, dass sowohl doSomething() als auch doSomethingElse() zurückkehren Promise-Objekte

Häufige Methoden:

doSomething().then(doSomethingElse).then(finalHandler);
doSomething
|-----------------|
         doSomethingElse(resultOfDoSomething)  //返回新promise,下一个then要收到新状态才执行
         |------------------|
                   finalHandler(resultOfDoSomethingElse)
                   |---------------------|

Häufige Problemumgehungen:

doSomething().then(function () { return doSomethingElse();}).then(finalHandler);
doSomething
|-----------------|
         doSomethingElse(undefined) //then外层函数的arguments[0]== resultOfDoSomething
         |------------------|
                   finalHandler(resultOfDoSomethingElse)
                   |------------------|

Falsche Methode 1:

doSomething().then(function () { doSomethingElse();}).then(finalHandler);
doSomething
|-----------------|
         doSomethingElse(undefined)  //虽然doSomethingElse会返回promise对象,但最外层的回调函数是return undefined,所以下一个then方法无需等待新promise的状态,会马上执行回调。
         |------------------|
         finalHandler(undefined)
         |------------------|

Falsche Methode 2:

doSomething().then(doSomethingElse()).then(finalHandler);
doSomething
|-----------------|
doSomethingElse(undefined)     //回调函数在注册时就直接被调用
|----------|
         finalHandler(resultOfDoSomething)
         |------------------|

Weitere Artikel zur Verwendung von Promise in JavaScript finden Sie auf der chinesischen PHP-Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn