The task of creating a promise for a function that returns nothing, such as setTimeout, can be initially challenging. To understand this concept, let's refer to a modified code sample:
<br>function async(callback){</p> <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">setTimeout(function(){ callback(); }, 5000);
}
async(function(){
console.log('async called back');
});
Our goal is to generate a promise that async can return once the setTimeout callback is ready.
Using native promises, we can create a function called later as follows:
<br>function later(delay) {</p> <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">return new Promise(function(resolve) { setTimeout(resolve, delay); });
}
This function takes a delay in milliseconds and returns a promise that resolves after the delay expires.
To modify later and allow it to pass a resolution value, we need to ensure the setTimeout callback receives the value as an argument. For browsers that support providing extra arguments to setTimeout, the following code can be used:
<br>function later(delay, value) {</p> <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">return new Promise(function(resolve) { setTimeout(resolve, delay, value); });
}
This code ensures that the value is passed to the callback and subsequently resolved by the promise.
For cases where we want to provide the ability to cancel the timeout, we can create an object with a cancel method and an accessor for the promise. When the cancel method is called, it clears the timeout and rejects the promise:
<br>const later = (delay, value) => {</p> <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">let timer = 0; let reject = null; const promise = new Promise((resolve, _reject) => { reject = _reject; timer = setTimeout(resolve, delay, value); }); return { get promise() { return promise; }, cancel() { if (timer) { clearTimeout(timer); timer = 0; reject(); reject = null; } } };
};
This approach provides a way to cancel a pending timeout and reject the associated promise.
The above is the detailed content of How to Turn a `setTimeout` Function into a Promise?. For more information, please follow other related articles on the PHP Chinese website!