Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use Promise and aysnc/await

2025-01-15 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

How to use Promise and aysnc/await, I believe that many inexperienced people do not know what to do. Therefore, this paper summarizes the causes and solutions of the problem. Through this article, I hope you can solve this problem.

Single-threading means that only one task can be completed at a time. If there are more than one task, you must wait in line. The previous task is completed, and then the latter task is executed. This "single-threaded" mode is inefficient and time-consuming.

To solve this problem, there is an asynchronous mode, also known as asynchronous programming.

I. Asynchronous programming

The so-called "asynchronous" means that a task is divided into two segments, first execute the first paragraph, then turn to other tasks, and then go back to execute the second paragraph when the first paragraph has the execution result.

JavaScript uses asynchronous programming for two reasons:

JavaScript is single-threaded.

In order to improve the utilization of CPU.

It not only improves the utilization of CPU, but also improves the difficulty of development, especially in the readability of the code.

Then the scenarios that exist asynchronously are:

Fs file operation

Require ("fs") .readFile (". / index.html", (err,data) = > {})

Database operation

AJAX

$.get ("/ user", (data) = > {})

Timer

SetTimeout (() = > {}, 2000) II. What is Promise? Promise understanding

(1) abstract expression

Promise is a new technology (es6 specification)

Promise is a new solution for asynchronous programming in js.

(2) specific expression

Syntactically, Promise is a constructor

Functionally, the Promise object is used to encapsulate an asynchronous operation and obtain the result value of its success / failure

Why use Promise

(1) the method of specifying callback function is more flexible.

Promise: start asynchronous task = > return promise object = > bind callback function to promise object

(2) chain call mode is supported to solve the callback hell problem.

What is callback hell?

Callback hell is the nested use of callback functions, and the result of asynchronous execution of external callback functions is the condition for the execution of nested callbacks.

Recall the shortcomings of the cellar.

Not easy to read

Not convenient for exception handling

Solution method

Status of Promise

Hongmeng official Strategic Cooperation to build HarmonyOS Technology Community

Promise must have three states: pending, rejected, and resolved

If the status of Promise is pending, it can become a successful fulfilled or a failed rejected

If promise is successful, it cannot be converted to any state, and a successful value is required, and this value cannot be changed

If promise is a failed state, it cannot be converted to any state, and a reason for the failure is required, and this value cannot be changed

State change of Promise

What is not determined by pending refers to the built-in properties of the instance status

(1) pending becomes resolved/fullfilled

(2) pending becomes rejected

Note: there are only two kinds of Promise state changes, and a Promise object can only be changed once, no matter failure or success will get a result output, the result of success is generally value, the result of failure is generally reason.

Promise is returned regardless of whether the status is successful or failed.

The value of Promise

Another property in the instance object, [PromiseResult], holds the result resolve/reject of the asynchronous task [success / failure].

Api of Promise

Api in handwritten Promide:

(1) promise constructor Promise (executor) {}

Executor: actuator (resolve,reject) = > {}

Resolve: the function we need to call if the internal definition is successful, value= > {}

Reject: the function we call when the internal definition fails > {} description: executor will be called synchronously within the Promise immediately, and the asynchronous operation will be performed in the executor

(2) Promise.prototype.then method: (onResolved,rejected) = > {}

OnResolved function: successful callback function value= > {}

Rejected function: failed callback function reason= > {}

Description: specify the successful callback to get the successful value and the failed callback to get the failed reason, and return a new promise object

(3) Promise.prototype.catch method: (onRejected) = > {}

The first three are the handwritten code that will be implemented in this article, and of course Promise has other api interfaces.

(1) Promise.prototype.finally () method

The finally () method is used to specify the actions that will be performed regardless of the final state of the Promise object. Regardless of the final state of the promise, the callback function specified by the finally method is executed after the callback function specified by then or catch is executed.

Promise .then (result = > {}) .catch (error = > {}) .finally (() = > {})

(2) Promise.all () method

The Promise.all () method is used to wrap multiple Promise instances into a new Promise instance.

Const p = Promise.all ([p1, p2, p3])

The state of p is determined by p1, p2 and p3 and is divided into two cases.

Only when the states of p1, p2, and p3 become fulfilled,p will they become fulfilled, and the return values of p1, p2, and p3 form an array and are passed to the callback function of p.

As long as one of p1, p2, and p3 becomes rejected, the return value of the first instance of reject will be passed to the callback function of p.

(3) Promise.race () method

The Promise.race () method also wraps multiple Promise instances into a new Promise instance.

Const p = Promise.race ([p1, p2, p3])

As long as one of p1, p2, and p3 takes the lead in changing the state, the state of p changes accordingly. The return value of the Promise instance that first changed is passed to the callback function of p.

(4) Promise.allSettled () method

The Promise.allSettled () method takes a set of Promise instances as parameters and wraps them as a new Promise instance. The wrapper instance will not end until all of these parameter instances return results, whether fulfilled or rejected.

Const promises = [fetch ('/ api-1'), fetch ('/ api-2'), fetch ('/ api-3'),]; await Promise.allSettled (promises); removeLoadingIndicator ()

The new Promise instance returned by this method, once finished, the state is always fulfilled and does not become rejected. When the state becomes fulfilled, the listener function of Promise receives an array of parameters, with each member corresponding to a Promise instance passed in to Promise.allSettled ().

(5) Promise.any () method

ES2021 introduces the Promise.any () method. This method takes a set of Promise instances as parameters and returns as a new Promise instance. As long as one of the parameter instances becomes fulfilled state, the wrapper instance becomes fulfilled state; if all parameter instances become rejected state, the wrapper instance becomes rejected state.

(6) Promise.reject (reason) method

The Promise.reject (reason) method also returns a new Promise instance with a status of rejected.

Const p = Promise.reject ('error'); / / equivalent to const p = new Promise ((resolve, reject) = > reject ('error')) p.then (null, function (s) {console.log (s)}); / / error occurred

(7) the Promise.resolve () method sometimes needs to convert an existing object to a Promise object, and the Promise.resolve () method does this.

Promise.resolve ('foo') / / is equivalent to new Promise (resolve = > resolve (' foo')) changing the promsie state and specifying the callback function who comes first?

(1) it is possible to specify the callback function first and then change the state, but you can also change the state first and then specify the callback function.

(2) how to change the status and specify a callback?

Call resolve/reject directly in the executor

Delay longer to call then

(3) when will the data be available?

If the callback is specified first, then when the state changes, the callback function will be called to get the data

If the state is changed first, then when the callback is specified, the callback function will be called to get the data

Example:

Let p = new Promise ((resolve,reject) = > {resolve ("successful"); reject ("failed");}); p.then ((value) = > {console.log (value);}, (reason) = > {console.log (reason);}) Promise specification

Hongmeng official Strategic Cooperation to build HarmonyOS Technology Community

"Promise" is an object or function with a then method that behaves in accordance with this specification. In other words, Promise is an object or function.

"thenable" is an object or function with a then method, that is, the object must have a then method

"value" is any legal js value (including undefined or promise)

Exceptions in promise need to be thrown using the throw statement

When promise fails, you need to give the reason for the failure.

Then method description

Hongmeng official Strategic Cooperation to build HarmonyOS Technology Community

A promise must have a then method and can access the final result of the promise, the value of success or failure

The then method needs to receive two parameters. Onfulfilled and onrejected are optional parameters.

Promise regardless of whether the then method is finished or not, as long as the state of the promise changes, the functions bound in the then will execute.

Chain call

The biggest advantage of Promise is that it can make chained calls, and if a then method returns a normal value, that value will be passed to the next then as a successful result.

If a promise is returned, the execution result of the promise will be passed on depending on the success or failure of the promise.

If an error is returned, it will be executed into the failure function of the next then.

Third, handwritten Promise code

The handwritten Promise code that is often tested in the interview can be understood carefully.

/ / handwritten Promise / / first defines a constructor that passes a function executor when creating a Promise object. / / this function is called immediately, so we execute this function immediately inside Promise. Function Promise (executor) {/ / used to save the state of promise this.status = "pending"; this.value;// initial value this.reason;// initial reason this.onResolvedCallbacks = []; / / stores all successful callback functions this.onRejectedCallbacks = [] / / store all failed callback functions / / define the resolve function const resolve = (value) = > {if (this.status = "pending") {this.status = "resolved"; this.value = value This.onResolvedCallbacks.forEach (function (fn) {fn ()})}} / / define the reject function const reject = (reason) = > {if (this.status = = "pending") {this.status = "rejected"; this.reason = reason This.onRejectedCallbacks.forEach (function (fn) {fn ()})} executor (resolve,reject) } Promise.prototype.then = function (onFulfilled,onRejected) {/ * each then will return a new promise. We need to get the result of the success or failure of the current then method, and the return value of the previous then method will be passed to the next then method, so here we should pay attention to the return values of onFulfilled (self.value) and onRejected (self.reason). We define an x here to receive it. If you fail to throw an error, you need to execute the reject method, and here you use try...catch to catch the error. That is, to judge the relationship between the execution result of the then function and the returned promise. * / return new Promise ((resolve Reject) = > {/ / when Promise status is resolved, if (this.status = "resolved") {try {resolve (onFulfilled (this.value))} catch (error) {reject (error)}} / / if (this.status) when Promise status is rejected = = "rejected") {try {resolve (onRejected (this.reason))} catch (error) {reject (error)}} / / when the Promise status is pendding if (this.status = = "pending") {this.onResolvedCallbacks.push (function () { Try {resolve (onFulfilled (this.value))} catch (error) {reject (error)}}) This.onRejectedCallbacks.push (function () {try {resolve (onRejected (this.reason))} catch (error) {reject (error)}});})}

Upgraded version of Promise:

Class Promise {/ * first defines a constructor that passes a function executor when the Promise object is created, which is called immediately, so we execute this function immediately inside Promise. * / constructor (executor) {this.executor = executor (this.resolve,this.reject); this.onResolvedCallbacks = []; / / store all successful callback functions this.onRejectedCallbakcs = []; / / store all failed callback functions} / / to store the corresponding state status = "pending"; / / initial value value / / initial reason reason; / / executor will pass in two methods when executing, one is resolve, / / a reject, so we need to create these two functions, and we need to pass them to executor. / / when we succeed or fail, execute the functions of onFulfilled and onRejected, / / that is, loop through the corresponding array of functions in the resolve function and the reject function, respectively. / / define success event resolve (value) {if (status = "pending") {status = "resolved"; value = value; this.onResolvedCallbacks.forEach (fn= > {fn ()})}} / / define failure event reject () {if (this.status = "pending") {this.status = "rejected" This.reason = reason; this.onRejectedCallbakcs.forEach (fn= > {fn ()});}} / / when we execute the resolve method asynchronously, the functions bound in then will execute, and when multiple then are bound, multiple methods will execute. There is a then method in the object of / / Promise. There will be two parameters in this then method, one is the successful callback onFulfilled, / / the other is the failed callback onRejected. As long as we call resolve, we will execute onFulfilled, and if we call reject, we will execute onRejected. / / to ensure that the this is messy, we define a self storage this. When we call resolve or reject, we need to change the state. / / it is important to note that the state of Promise can only be changed once, so we have to judge that the state can be changed only when the state has not changed. Then (onFulfilled,onRejected) {/ / judge the current status and call back if (this.status = = "resolved") {onFulfilled (self.value)} If (this.status = = "rejected") {onRejected (self.reason)} / / when the state is still in pending state / / because onFulfilled and onRejected need to pass the corresponding value value when executing, so we wrap it in a function and pass in the corresponding value. If (this.status = "pending") {this.onResolvedCallbacks.push (() = > {onFulfilled (this.value)}); this.onResolvedCallbacks.push (() = > {onRejected (this.reason)});}

Use your own handwritten Promise source code:

Let p = new Promise ((resolve,reject) = > {setTimeout (()) = > {resolve ("successful")}, 1000)}); p.then (function (value) {return 123;}) .then (value= > {console.log ("successful message received:", value);}) .catch (error= > {console.log (error);}); p.then (value= > {console.log (value)) }) IV. Async/Await

Async is used to indicate that the function is asynchronous, and the return value of the defined async function is a promise object, and you can add a callback function using the then method.

Await can be understood as an abbreviation for async wait. Await must appear inside the async function and cannot be used alone. As long as await is used in the function, the current function must be decorated with async.

So the Terminator of the callback function is async/await.

Async command

The async function returns a promise object.

The value returned by the return statement inside the async function becomes a parameter for the callback of the then method.

An error is thrown inside the async function, which causes the returned Promise object to become reject.

The error object thrown will be received by the callback function of the catch method.

The state of the Promise object returned by the async function will not change until the execution of the Promise object after all internal await commands is completed, unless an declare statement is encountered or an error is thrown.

That is, the callback function specified by the then method will not be executed until the asynchronous operation within the async function has been executed.

Async function fun () {/ / return "hello wenbo"; throw new Error ("ERROR");} fun (). Then (v = > console.log (v), reason= > console.log (reason)); / / Error: error ``await command

Normally, the await command is followed by a Promise object that returns the result of that object. If it is not a Promise object, the corresponding value is returned directly.

Async function fun () {return await "zhaoshun"; / / equivalent to return "zhaoshun";} fun () .then (value= > console.log (value)); / / zhaoshun

Alternatively, if the await command is followed by a thenable object (that is, the object that defines the then method), await equates it to the Promise object.

Class Sleep {constructor (timeout) {this.timeout = timeout;} then (resolve,reject) {const startTime = Date.now (); setTimeout () = > resolve (Date.now ()-startTime), this.timeout);} (async () = > {const sleepTime = await new Sleep (1000); console.log (sleepTime)) / / 1012}) () / / there is no sleep syntax in js, but with the help of the await command, you can make the program pause const sleepFun = (interval) = > {return new Promise (resolve= > {setTimeout (resolve,interval);})} / / usage const asyncFun = async () = > {for (let I = 1; I {try {await Promise.reject ("ERROR")) } catch (error) {} return await Promise.resolve ("success");} fun (). Then (value= > console.log (value), reason= > console.log (reason, "error") / /). Catch (error= > console.log (error) / / ERROR)

Another way is to follow the Promise object after the await with a catch method to handle the errors that may occur earlier.

Const fun = async () = > {await Promise.reject ("error") .catch (e = > console.log (e)); return await Promise.resolve ("success");} fun () .then (v = > console.log (v)); / / success error handling

The first point: if the asynchronous operation after await goes wrong, it is equivalent to the promise object that follows the async function is reject.

Const fun = async () = > {await new Promise ((resolve,reject) = > {throw new Error ("error")})} fun () .then (v = > console.log (v)) .catch (e = > console.log (e)

The second point: asynchronous operations following multiple await commands, if there is no secondary relationship, it is best to let them trigger at the same time.

Const [fun1,fun2] = await Promise.all ([getFun (), getFoo ()]); const fooPromise = getFoo (); const funPromise = getFun (); const fun1 = await fooPromise (); const fun2 = await funPromise ()

The third point: the await command can only be used in async functions. If it is used in ordinary functions, an error will be reported.

Async function dbFuc (db) {let docs = [{}, {}, {}]; / / docs.forEach (function (doc) {await db.post (doc);});}

Fourth: the async function preserves the run stack.

After reading the above, have you mastered how to use Promise and aysnc/await? If you want to learn more skills or want to know more about it, you are welcome to follow the industry information channel, thank you for reading!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report