Rewrite the title as: How to convert existing callback API to Promise form?
P粉268654873
2023-08-21 18:34:55
<p>I want to use promises to handle it, but the format of my callback API is as follows: </p>
<h3>1. DOM loading or other one-time events: </h3>
<pre class="brush:php;toolbar:false;">window.onload; // Set as callback function
...
window.onload = function() {
};</pre>
<h3>2. Ordinary callback function: </h3>
<pre class="brush:php;toolbar:false;">function request(onChangeHandler) {
...
}
request(function() {
// changed
...
});</pre>
<h3>3. Node-style callback function ("nodeback"): </h3>
<pre class="brush:php;toolbar:false;">function getStuff(dat, callback) {
...
}
getStuff("dataParam", function(err, data) {
...
})</pre>
<h3>4. The entire library uses Node-style callback functions: </h3>
<pre class="brush:php;toolbar:false;">API;
API.one(function(err, data) {
API.two(function(err, data2) {
API.three(function(err, data3) {
...
});
});
});</pre>
<h3>How do I use promises to handle this API and how do I "promisify" it? </h3>
Today, I can use
Promise
as a normal Javascript method inNode.js
.A simple and basic
Promise
example (using the KISS method):NormalJavascript asynchronous API code:
Promise
Javascript asynchronous API code:(I recommend visiting this excellent source )
In addition,
Promise
can also be used withasync\await
inES7
to make the program flow wait for thefulfilled
result, as follows Shown:Using the same code, you can use the
.then()
method:Promise
can also be used on any Node.js-based platform, such asreact-native
.Bonus: A hybridapproach
(Assume that the callback method has two parameters, namely error and result)
The above method can respond to the results of old-style callbacks and Promise usage at the same time.
Hope this helps.
Promises have a state, they start out in a pending state and can be resolved as:
Functions that return a promise should not throw an exception but should return a rejection. Throwing an exception from a function that returns a promise will force you to use both
} catch {
and.catch
. People using promise-based APIs don't want promises to throw exceptions. If you're not sure how the async API in JS works, first check out this answer.1. DOM loading or other one-time events:
Therefore, creating promises usually means specifying when they resolve - meaning when they move to the Fulfilled or Rejected stage to indicate that the data is available (and accessible using
.then
).Use a modern promise implementation that supports
Promise
constructors (such as native ES6 promises):You can then use the generated promise like this:
Use a library that supports delay (here we use $q as an example, but we will also use jQuery later):
Or use an API similar to jQuery to hook an event that occurs:
2. Ordinary callback:
These APIs are quite common because callbacks are common in JS. Let's look at
onSuccess
andonFail
in common cases:Use a modern promise implementation that supports
Promise
constructors (such as native ES6 promises):Use a library that supports delay (here we're using jQuery as an example, but we also used $q before):
jQuery also provides the
$.Deferred(fn)
form, which has the advantage of allowing us to write an expression very close to thenew Promise(fn)
form, as shown below :Note: Here we take advantage of the fact that jQuery's deferred
resolve
andreject
methods are "detachable"; that is, they are bound to jQuery.Deferred()'s Example. Not all libraries provide this functionality.3. Node style callback ("nodeback"):
Node style callbacks (nodebacks) have a specific format where the callback is always the last parameter and its first parameter is the error. First manually convert it to a promise:
Convert to:
Using defer, you can do the following (we used Q as an example, although Q now supports a new syntax You should prefer that syntax ):
In general you shouldn't manually convert things to promises too much, most promise libraries designed for Node as well as native promises in Node 8 have built-in methods for converting nodebacks to promises. For example
4. The entire library uses Node style callbacks:
There is no golden rule here, you can convert them into promises one by one. However, some promise implementations allow you to do this in batches, for example in Bluebird converting the nodeback API to a promise API is as simple as this:
Or use Native Promise in Node:
Notice:
.then
handler. Returning a promise from the.then
handler will be resolved or rejected using the value of the promise. It is also good practice to throw an exception from the.then
handler, which will reject the promise - this is known as promise-throwing safety.onload
case, you should useaddEventListener
instead ofonX
.