관련 추천: "javascript 비디오 튜토리얼"
JS는 1996년 출시 이후 꾸준히 개선되어 왔습니다. ECMAScript 버전이 많이 개선되어 최신 버전은 ES2020
입니다. JS의 중요한 업데이트는 2015년에 ES6라는 이름으로 출시된 Promise입니다. ES2020
。JS 的一个重要更新是Promise,在2015年,它以 ES6 的名义发布。
MDN 上对 Promise 的定义:Promise 对象用于表示一个异步操作的最终完成 (或失败)及其结果值。对于新手来说,这听起来可能有点太复杂了。
国外一位大什么对Promises
的解释如下:“想象一下你是个孩子。 你老妈向你保证,她下周会给你买一部新手机。”
你要到下周才能知道你是否能获取那部手机。你老妈要么真的给你买了一个全新的手机,要么因为不开心就不给你买。
这个就是一个Promise
。 一个Promise
有三个状态。 分别是:
这个是我目前听到,最快能理解 Promise 事例。
如果你还没有开始学习 Promise ,建议你这样做。
Promise包含几种非常有用的内置方法。 今天我们主要介绍这两种方法。
Promise.race()
-与 ES6 一起发布Promise.any()
-仍处于第4阶段的提案中Promise.race()
方法最初是在 ES6 中引入 Promise 时发布的,这个方法需要一个iterable
作为参数。
Promise.race(iterable)
方法返回一个 promise,一旦迭代器中的某个promise
解决或拒绝,返回的 promise 就会解决或拒绝。
与Promise.any()
方法不同,Promise.race()
方法主要关注 Promise 是否已解决,而不管其被解决还是被拒绝。
Promise.race(iterable)
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拒绝
现在,你可能想知道,我们在实战中何时 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(); });
取消的 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);
批处理请求,用于长时间执行
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 });
Promise.any()
接收一个Promise
可迭代对象,只要其中的一个 promise
成功,就返回那个已经成功的 promise
。如果可迭代对象中没有一个 promise
成功(即所有的 promises
都失败/拒绝),就返回一个失败的 promise 和AggregateError
类型的实例,它是 Error 的一个子类,用于把单一的错误集合在一起。本质上,这个方法和Promise.all()
약속
을 다음과 같이 설명했습니다. "당신이 어린아이라고 상상해 보세요. 어머니가 다음 주에 새 휴대폰을 사주겠다고 약속하십니다."🎜🎜You 당신은 알지 못할 것입니다. 다음 주까지 그 전화를 받을 수 있을지 말이에요. 당신의 엄마는 실제로 당신에게 새 휴대폰을 사줄 수도 있고, 아니면 마음에 들지 않아서 사주지 않을 수도 있습니다. 🎜🎜이것은 약속
입니다. Promise
에는 세 가지 상태가 있습니다. 🎜Promise.race()
- ES6으로 출시됨 Promise.any()
- 아직 4단계 제안서에 있음 Promise.race()
메소드는 원래 Promise가 ES6에 도입되었을 때 출시되었습니다. 이 메소드에는 반복 가능
을 매개변수로 사용합니다. 🎜🎜Promise.race(iterable)
메서드는 반복자의 promise
가 해결되거나 거부되면 해결되거나 거부될 Promise를 반환합니다. 🎜🎜Promise.any()
메서드와 달리 Promise.race()
메서드는 주로 Promise의 해결 여부에 관계없이 Promise의 해결 여부에 중점을 둡니다. . 🎜Promise.any(iterable);
iterable
— 배열과 유사한 반복 가능한 객체입니다. 반복 가능한 객체는 Symbol.iterator
메서드를 구현합니다. 🎜iterable
을 허용하므로 기본 값이나 심지어 배열의 객체와 같은 일부 값을 전달할 수 있습니다. 이 경우 race
메소드는 전달된 첫 번째 비Promise 객체를 반환합니다. 이는 주로 메서드의 동작이 값을 사용할 수 있게 되자마자(프라미스가 충족될 때) 값을 반환하는 것이기 때문입니다. 🎜🎜 또한, 해결된 Promise가 iterable
에 전달되면 Promise.race()
메서드는 해당 값의 첫 번째 값으로 해결됩니다. 빈 Iterable
이 전달되면 race
메서드는 항상 보류됩니다. 🎜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"
Promise.race()
메서드를 사용하면 됩니다. 🎜rrreee🎜취소된 약속 🎜🎜어떤 경우에는 약속을 취소해야 할 수도 있습니다. 이 경우 Promise.race()
메서드를 사용할 수도 있습니다. 🎜rrreee 🎜장기 실행에 대한 요청 일괄 처리🎜🎜Chris Jensen에는 race()
메서드에 대한 흥미로운 사용 사례가 있습니다. 그는 Promise.race()
메서드를 사용하여 장기 실행 요청을 일괄 처리했습니다. 이렇게 하면 병렬 요청 수를 고정된 상태로 유지할 수 있습니다. 🎜rrreeePromise.any()
는 Promise
반복 가능한 객체를 받습니다. 성공하면 성공적인 프라미스
를 반환합니다. 반복 가능 항목의 promise
중 어느 것도 성공하지 않으면(즉, 모든 promise
실패/거부) 실패한 Promise와 AggregateError
유형이 반환됩니다. Error의 하위 클래스이며 단일 오류를 그룹화하는 데 사용되는 Error 인스턴스입니다. 기본적으로 이 메서드는 Promise.all()
과 반대입니다. 🎜注意! Promise.any()
方法依然是实验性的,尚未被所有的浏览器完全支持。它当前处于 TC39 第四阶段草案(Stage 4)
Promise.any(iterable);
iterable
— 个可迭代的对象, 例如 Array。
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"
从上面代码注意到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
更多编程相关知识,请访问:编程入门!!
위 내용은 Promise.race() 및 Promise.any() 사용 방법 이해의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!