Heim > Web-Frontend > js-Tutorial > Hauptteil

Verstehen Sie, wie Promise.race() und Promise.any() verwendet werden

青灯夜游
Freigeben: 2020-12-21 09:32:08
nach vorne
3804 Leute haben es durchsucht

Verstehen Sie, wie Promise.race() und Promise.any() verwendet werden

Verwandte Empfehlungen: „Javascript-Video-Tutorial

Seit seiner Veröffentlichung im Jahr 1996 hat sich JS stetig verbessert. Mit vielen Verbesserungen in ECMAScript-Versionen ist die neueste Version ES2020. Ein wichtiges Update für JS ist Promise, das 2015 unter dem Namen ES6 veröffentlicht wurde. ES2020。JS 的一个重要更新是Promise,在2015年,它以 ES6 的名义发布。

什么是 Promise ?

MDN 上对 Promise 的定义:Promise 对象用于表示一个异步操作的最终完成 (或失败)及其结果值。对于新手来说,这听起来可能有点太复杂了。

国外一位大什么对Promises的解释如下:“想象一下你是个孩子。 你老妈向你保证,她下周会给你买一部新手机。”

你要到下周才能知道你是否能获取那部手机。你老妈要么真的给你买了一个全新的手机,要么因为不开心就不给你买。

这个就是一个Promise。 一个Promise有三个状态。 分别是:

  1. Pending:你不知道你是否能得到那部手机
  2. Fulfilled:老妈高兴了,给你买了
  3. Rejected:老娘不开森了,不给你买了

这个是我目前听到,最快能理解 Promise 事例。

如果你还没有开始学习 Promise ,建议你这样做。

Promise包含几种非常有用的内置方法。 今天我们主要介绍这两种方法。

  • Promise.race()-与 ES6 一起发布
  • Promise.any() -仍处于第4阶段的提案中

Promise.race()

Promise.race()方法最初是在 ES6 中引入 Promise 时发布的,这个方法需要一个iterable作为参数。

Promise.race(iterable) 方法返回一个 promise,一旦迭代器中的某个promise解决或拒绝,返回的 promise 就会解决或拒绝。

Promise.any()方法不同,Promise.race()方法主要关注 Promise 是否已解决,而不管其被解决还是被拒绝。

语法

Promise.race(iterable)
Nach dem Login kopieren

参数

iterable — 可迭代对象,类似 Array。 iterable 对象实现Symbol.iterator方法。

返回值

一个待定的 Promise 只要给定的迭代中的一个promise解决或拒绝,就采用第一个promise的值作为它的值,从而异步地解析或拒绝(一旦堆栈为空)。

注意

因为参数接受iterable,所以我们可以传递一些值,比如基本值,甚至数组中的对象。在这种情况下,race方法将返回传递的第一个非 promise 对象。这主要是因为方法的行为是在值可用时(当 promise 满足时)立即返回值。

此外,如果在iterable中传递了已经解决的Promise,则Promise.race()方法将解析为该值的第一个。 如果传递了一个空的Iterable,则race方法将永远处于待处理状态。

事例

const promise1 = new Promise((resolve, reject) => {
    setTimeout(resolve, 500, 'promise 1 resolved');
});

const promise2 = new Promise((resolve, reject) => {
    setTimeout(reject, 100, 'promise 2 rejected');
});

const promise3 = new Promise((resolve, reject) => {
    setTimeout(resolve, 200, 'promise 3 resolved')
});

(async () => {
    try {
        let result = await Promise.race([promise1, promise2, promise3]);
        console.log(result);
    } catch (err) {
        console.error(err);
    }
})();
  // 输出- "promise 2 rejected"
  // 尽管promise1和promise3可以解决,但promise2拒绝的速度比它们快。
  // 因此Promise.race方法将以promise2拒绝
Nach dem Login kopieren

真实用例

现在,你可能想知道,我们在实战中何时 Promise.race() ? 来看看。

在请求数据时,显示加载动画

使用加载动画开发中是非常常见。当数据响应时间较长时,如果没使用加载动画,看起来就像没有响应一样。但有时,响应太快了,我们需要加载动画时,增加一个非常小延迟时间,这样会让用户觉得我是在经常请求过来的。要实现这一点,只需使用Promise.race()方法,如下所示。

function getUserInfo(user) {
  return new Promise((resolve, reject) => {
    // had it at 1500 to be more true-to-life, but 900 is better for testing
    setTimeout(() => resolve("user data!"), Math.floor(900*Math.random()));
  });
}

function showUserInfo(user) {
  return getUserInfo().then(info => {
    console.log("user info:", info);
    return true;
  });
}

function showSpinner() {
  console.log("please wait...")
}

function timeout(delay, result) {
  return new Promise(resolve => {
    setTimeout(() => resolve(result), delay);
  });
}
Promise.race([showUserInfo(), timeout(300)]).then(displayed => {
  if (!displayed) showSpinner();
});
Nach dem Login kopieren

取消的 Promise

有些情况下,我们需要取消 Promise,这时也可以借助 Promise.race() 方法:

function timeout(delay) {
  let cancel;
  const wait = new Promise(resolve => {
    const timer = setTimeout(() => resolve(false), delay);
    cancel = () => {
      clearTimeout(timer);
      resolve(true);
    };
  });
  wait.cancel = cancel;
  return wait;
}


function doWork() {
  const workFactor = Math.floor(600*Math.random());
  const work = timeout(workFactor);
  
  const result = work.then(canceled => {
    if (canceled)
      console.log('Work canceled');
    else
      console.log('Work done in', workFactor, 'ms');
    return !canceled;
  });
  result.cancel = work.cancel;
  return result;
}

function attemptWork() {
  const work = doWork();
  return Promise.race([work, timeout(300)])
    .then(done => {
      if (!done)
        work.cancel();
      return (done ? 'Work complete!' : 'I gave up');
  });
}

attemptWork().then(console.log);
Nach dem Login kopieren

批处理请求,用于长时间执行

Chris Jensen 有一个有趣的race()方法用例。 他曾使用Promise.race()方法批处理长时间运行的请求。 这样一来,他们可以保持并行请求的数量固定。

const _ = require('lodash')

async function batchRequests(options) {
    let query = { offset: 0, limit: options.limit };

    do {
        batch = await model.findAll(query);
        query.offset += options.limit;

        if (batch.length) {
            const promise = doLongRequestForBatch(batch).then(() => {
                // Once complete, pop this promise from our array
                // so that we know we can add another batch in its place
                _.remove(promises, p => p === promise);
            });
            promises.push(promise);

            // Once we hit our concurrency limit, wait for at least one promise to
            // resolve before continuing to batch off requests
            if (promises.length >= options.concurrentBatches) {
                await Promise.race(promises);
            }
        }
    } while (batch.length);

    // Wait for remaining batches to finish
    return Promise.all(promises);
}

batchRequests({ limit: 100, concurrentBatches: 5 });
Nach dem Login kopieren

Promise.any()

Promise.any() 接收一个Promise可迭代对象,只要其中的一个 promise 成功,就返回那个已经成功的 promise 。如果可迭代对象中没有一个 promise 成功(即所有的 promises 都失败/拒绝),就返回一个失败的 promise 和AggregateError类型的实例,它是 Error 的一个子类,用于把单一的错误集合在一起。本质上,这个方法和Promise.all()

Was ist Versprechen?

Definition von Promise auf MDN: Promise-Objekte werden verwendet, um den endgültigen Abschluss (oder Fehler) eines asynchronen Vorgangs und seinen Ergebniswert darzustellen. Für Neulinge klingt das vielleicht etwas zu kompliziert. 🎜🎜Ein ausländischer Ältester erklärte Promises wie folgt: „Stellen Sie sich vor, Sie wären ein Kind. Ihre Mutter verspricht Ihnen, dass sie Ihnen nächste Woche ein neues Mobiltelefon kaufen wird. 🎜🎜Sie werden es nicht herausfinden.“ Ich werde bis nächste Woche fragen, ob du das Telefon bekommen kannst. Deine Mutter wird dir entweder tatsächlich ein brandneues Telefon kaufen, oder sie wird es nicht für dich kaufen, weil sie unzufrieden ist. 🎜🎜Dies ist ein Versprechen. Ein Promise hat drei Zustände. Sie sind: 🎜
  1. Ausstehend: Du weißt nicht, ob du das Telefon bekommen kannst
  2. Erfüllt: Mama ist glücklich und hat es für dich gekauft
  3. Abgelehnt: Mama Es tut mir leid, ich werde es nicht für Sie kaufen
🎜Das ist der schnellste Weg, das Promise-Beispiel zu verstehen, das ich bisher gehört habe. 🎜🎜Wenn Sie noch nicht mit dem Erlernen von Promise begonnen haben, empfehle ich Ihnen, dies zu tun. 🎜🎜Promise enthält mehrere sehr nützliche integrierte Methoden. Heute stellen wir hauptsächlich diese beiden Methoden vor. 🎜
  • Promise.race() – Veröffentlicht mit ES6
  • Promise.any() – Noch in Stufe 4 Im Vorschlag

Promise.race()

🎜Promise.race()-Methode wurde ursprünglich veröffentlicht, als Promise in ES6 eingeführt wurde. Diese Methode erfordert einen iterable als Parameter. Die Methode 🎜🎜Promise.race(iterable) gibt ein Versprechen zurück, das aufgelöst oder abgelehnt wird, sobald ein promise im Iterator aufgelöst oder abgelehnt wird. 🎜🎜Im Gegensatz zur Methode Promise.any() konzentriert sich die Methode Promise.race() hauptsächlich darauf, ob das Versprechen gelöst wurde, unabhängig davon, ob es gelöst oder abgelehnt wird . 🎜

Syntax

Promise.any(iterable);
Nach dem Login kopieren
Nach dem Login kopieren

Parameter

🎜iterable – Iterierbares Objekt, ähnlich wie Array. iterierbare Objekte implementieren die Methode Symbol.iterator. 🎜

Rückgabewert

🎜Ein ausstehendes Versprechen nimmt den Wert des ersten Versprechens als Wert an, wenn ein Versprechen in einer bestimmten Iteration aufgelöst oder abgelehnt wird, also Hinweis🎜Da der Parameter iterable akzeptiert, können wir einige Werte übergeben, z. B. Grundwerte oder sogar Objekte in einem Array. In diesem Fall gibt die Methode race das erste übergebene Non-Promise-Objekt zurück. Dies liegt hauptsächlich daran, dass das Verhalten der Methode darin besteht, den Wert zurückzugeben, sobald der Wert verfügbar ist (wenn das Versprechen erfüllt ist). 🎜🎜 Wenn außerdem ein aufgelöstes Promise in einem iterable übergeben wird, löst die Methode Promise.race() den ersten Wert dieses Werts auf. Wenn ein leeres Iterable übergeben wird, steht die Methode race immer an. 🎜

Beispiele

const promise1 = new Promise((resolve, reject) => {
  setTimeout(reject, 100, 'promise 1 rejected');
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 400, 'promise 2 resolved at 400 ms');
});

const promise3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 700, 'promise 3 resolved at 800 ms');
});

(async () => {
  try {
    let value = await Promise.any([promise1, promise2, promise3]);
    console.log(value);
  } catch (error) {
    console.log(error);
  }
})();

//Output - "promise 2 resolved at 400 ms"
Nach dem Login kopieren
Nach dem Login kopieren

Echte Anwendungsfälle

🎜Nun fragen Sie sich vielleicht, wann wir Promise.race() in der Praxis verwenden? Kommen Sie vorbei und schauen Sie es sich an. 🎜🎜Ladeanimation beim Anfordern von Daten anzeigen🎜🎜In der Entwicklung werden häufig Ladeanimationen verwendet. Wenn die Datenantwortzeit lang ist und die Ladeanimation nicht verwendet wird, sieht es so aus, als gäbe es keine Antwort. Aber manchmal ist die Antwort zu schnell. Wir müssen beim Laden der Animation eine sehr kleine Verzögerungszeit hinzufügen, was dem Benutzer das Gefühl gibt, dass ich häufig nachfrage. Um dies zu erreichen, verwenden Sie einfach die Methode Promise.race() wie unten gezeigt. 🎜rrreee🎜Cancelled Promise🎜🎜In manchen Fällen müssen wir das Promise stornieren. In diesem Fall können wir auch die Methode Promise.race() verwenden: 🎜rrreee 🎜Batchverarbeitungsanfragen für lange Ausführung🎜🎜Chris Jensen hat einen interessanten Anwendungsfall für die Methode race(). Er verwendete die Methode Promise.race(), um lang laufende Anfragen zu stapeln. Auf diese Weise können sie die Anzahl paralleler Anfragen konstant halten. 🎜rrreee

Promise.any()

🎜Promise.any() empfängt ein iterierbares Promise-Objekt, solange eines der promise Bei Erfolg wird das erfolgreiche Versprechen zurückgegeben. Wenn keines der Versprechen im iterierbaren Objekt erfolgreich ist (d. h. alle Versprechen schlagen fehl/ablehnen), werden ein fehlgeschlagenes Versprechen und ein AggregateError-Typ zurückgegeben Instanz von Error, die eine Unterklasse von Error ist und zur Gruppierung einzelner Fehler verwendet wird. Im Wesentlichen ist diese Methode das Gegenteil von Promise.all(). 🎜
注意! Promise.any() 方法依然是实验性的,尚未被所有的浏览器完全支持。它当前处于 TC39 第四阶段草案(Stage 4)

语法

Promise.any(iterable);
Nach dem Login kopieren
Nach dem Login kopieren

参数

iterable — 个可迭代的对象, 例如 Array。

返回值

  • 如果传入的参数是一个空的可迭代对象,则返回一个 已失败(already rejected) 状态的 Promise
  • 如果传入的参数不包含任何 promise,则返回一个 异步完成 (asynchronously resolved)的 Promise。
  • 其他情况下都会返回一个处理中(pending) 的 Promise。 只要传入的迭代对象中的任何一个 promise 变成成功(resolve)状态,或者其中的所有的 promises 都失败,那么返回的 promise 就会 异步地(当调用栈为空时) 变成成功/失败(resolved/reject)状态。

说明

这个方法用于返回第一个成功的 promise 。只要有一个 promise 成功此方法就会终止,它不会等待其他的 promise 全部完成。

不像 Promise.all() 会返回一组完成值那样(resolved values),我们只能得到一个成功值(假设至少有一个 promise 完成)。当我们只需要一个 promise 成功,而不关心是哪一个成功时此方法很有用的。

同时, 也不像 Promise.race() 总是返回第一个结果值(resolved/reject)那样,这个方法返回的是第一个 成功的 值。这个方法将会忽略掉所有被拒绝的 promise,直到第一个 promise 成功。

事例

const promise1 = new Promise((resolve, reject) => {
  setTimeout(reject, 100, 'promise 1 rejected');
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 400, 'promise 2 resolved at 400 ms');
});

const promise3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 700, 'promise 3 resolved at 800 ms');
});

(async () => {
  try {
    let value = await Promise.any([promise1, promise2, promise3]);
    console.log(value);
  } catch (error) {
    console.log(error);
  }
})();

//Output - "promise 2 resolved at 400 ms"
Nach dem Login kopieren
Nach dem Login kopieren

从上面代码注意到Promise.any()主要关注解析的值。 它会忽略在100毫秒时拒绝的promise1,并考虑在400毫秒后解析的promise2的值。

真实用例

从最快的服务器检索资源

假设访问我们网站的用户可能来自全球各地。如果我们的服务器基于单个位置,那么响应时间将根据每个用户的位置而不同。但是如果我们有多个服务器,可以使用能够产生最快响应的服务器。在这种情况下,可以使用Promise.any()方法从最快的服务器接收响应。

原文地址:https://blog.bitsrc.io/introduction-to-promise-race-and-promise-any-with-real-life-examples-9d8d1b9f8ec9

作者:Mahdhi Rezvi

译文地址:https://segmentfault.com/a/1190000038475001

更多编程相关知识,请访问:编程入门!!

Das obige ist der detaillierte Inhalt vonVerstehen Sie, wie Promise.race() und Promise.any() verwendet werden. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:segmentfault.com
Erklärung dieser Website
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
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage