author :Mahdhi Rezvi
translator : The front end little wisdom
source : medium
Have dreams , There are dry goods , WeChat search 【 The big move the world 】 Pay attention to this dish washing wisdom who is still washing dishes in the early morning .
this paper GitHub https://github.com/qq449245884/xiaozhi Included , There is a complete interview site for a large factory 、 Materials and my series .
since 1996 Since its release ,JS Has been steadily improving . With ECMAScript Many improvements to the version , The latest version is ES2020.JS An important update of is Promise, stay 2015 year , It uses ES6 In the name of .
What is? Promise ?
MDN Yes Promise The definition of :Promise Object is used to represent the final completion of an asynchronous operation ( Or failure ) And its result value . For starters , It may sound a little too complicated .
What's wrong with a foreign person Promises Is explained as follows :“ Imagine you're a child . Your mom promised you , She will buy you a new mobile phone next week .”
You don't know if you can get that phone next week . Your mom either actually bought you a brand new cell phone , Or I won't buy you because I'm not happy .
This is a Promise. One Promise There are three states . Namely :
- Pending: You don't know if you can get that phone
- Fulfilled: Mom is happy , I bought you
- Rejected: I don't care anymore , I won't buy you
This is what I've heard so far , The quickest way to understand Promise Example .
If you haven't started learning yet Promise , I suggest you do this .
Promise There are several very useful built-in methods . Today we mainly introduce these two methods .
Promise.race()- And ES6 Release togetherPromise.any()- Still in the first place 4 In the stage proposal
Promise.race()
Promise.race() The method was originally used in ES6 Introduction in Promise When it was released , This method needs a iterable As a parameter .
Promise.race(iterable) Method returns a promise, Once one of the iterators promise To settle or refuse , Back to promise Will solve or refuse .
And Promise.any() The method is different ,Promise.race() Methods focus on Promise Whether it has been solved , Whether it's solved or rejected .
grammar
Promise.race(iterable)Parameters
iterable — Iteratable object , similar Array. iterable Object implementation Symbol.iterator Method .
Return value
One Pending Promise As long as one of the given iterations promise To settle or refuse , Take the first one promise As its value , thus asynchronous To resolve or reject ( Once the stack is empty ).
Be careful
Because parameters accept iterable, So we can pass some values , For example, the basic value , Even objects in arrays . under these circumstances ,race Method will return the first non passed promise object . This is mainly because the behavior of the method is when the value is available ( When promise When satisfied ) Immediate return value .
Besides , If in iterable It passed on the solved Promise, be Promise.race() Method resolves to the first... Of the value . If an empty Iterable, be race Method will always be in a pending state .
Example
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);
}
})();
// Output - "promise 2 rejected"
// Even though promise1 and promise3 Can solve , but promise2 Rejection is faster than they are .
// therefore Promise.race Method will promise2 Refuse Real use cases
Now? , You may want to know , When are we going to Promise.race() ? Let's see .
When requesting data , Display load animation
It is very common to use load animation development . When the data response time is long , If you don't use load animation , It looks like there's no response . But sometimes , The response was too fast , When we need to load animation , Add a very small delay time , This will make users feel that I am frequently asking for it . To achieve this , Just use Promise.race() Method , As shown below .
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();
});Cancelled Promise
In some cases , We need to cancel Promise, You can also use Promise.race() Method :
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);Batch request , For long-term execution
Chris Jensen There's an interesting one race() Method use cases . He used Promise.race() Method to batch long running requests . thus , They can keep the number of parallel requests fixed .
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.any() Receive one Promise Iteratable object , Just one of them promise success , Just go back to the successful one promise . If there is not one of the iteratable objects promise success ( That all the promises All failed / Refuse ), Just return a failed promise and AggregateError Instance of type , It is Error A subclass of , Used to group single errors together . Essentially , This method and Promise.all() It's the opposite .
Be careful ! Promise.any() The method is still experimental , Not fully supported by all browsers . It is currently in TC39 The fourth stage draft (Stage 4) grammar
Promise.any(iterable);Parameters
iterable — An iteratable object , for example Array.
Return value
- If the parameter passed in is an empty iteratable object , Returns a Failed (already rejected) State of
Promise. - If the parameter passed in does not contain any promise, Returns a Asynchronous completion (asynchronously resolved) Of Promise.
- In other cases, it will return a In processing (pending) Of Promise. As long as any one of the iteration objects passed in
promiseBecome successful (resolve) state , Or all of itpromisesAll failed , So backpromisewill Asynchronously ( When the call stack is empty ) Become successful / Failure (resolved/reject) state .
explain
This method is used to return the first successful promise . As long as there is one promise If successful, the method will terminate , It won't wait for anything else promise Complete .
Unlike Promise.all() It will return a set of completion values (resolved values), We can only get one success value ( Suppose there is at least one promise complete ). When we just need one promise success , It's useful when you don't care which one is successful .
meanwhile , It's not like Promise.race() Always return the first result value (resolved/reject) like that , This method returns the first The success of value . This method will ignore all rejected promise, Until the first one promise success .
Example
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" Notice from the code above Promise.any() The main concern is the parsed values . It ignores the fact that 100 Rejected in milliseconds promise1, And consider in 400 Resolved in milliseconds promise2 Value .
Real use cases
Retrieve resources from the fastest server
Suppose the users visiting our website may come from all over the world . If our server is based on a single location , The response time will vary depending on the location of each user . But if we have multiple servers , You can use the server that produces the fastest response . under these circumstances , have access to Promise.any() Method to receive the response from the fastest server .
This is Xiaozhi , See you next time !
Possible after code deployment BUG There's no way to know in real time , In order to solve these problems afterwards BUG, It took a lot of time log debugging , This way, I'd like to recommend an easy-to-use one for you BUG Monitoring tools Fundebug.
original text :https://blog.bitsrc.io/introd...
communication
Have dreams , There are dry goods , WeChat search 【 The big move the world 】 Pay attention to this dish washing wisdom who is still washing dishes in the early morning .
this paper GitHub https://github.com/qq44924588... Included , There is a complete interview site for a large factory 、 Materials and my series .








