I am using the async/await function the following way
async function(){ let output = await string.replace(regex, async (match)=>{ let data = await someFunction(match) console.log(data); //gives correct data return data }) return output; }
But the returned data is an promise object. Just confused about the way it should be implemented in such functions with callback.
There are a few alternative async/await transpilers to Regenerator, which take async code and attempt to convert to more traditional . then and . catch notation. In my experience, these transpilers work pretty well for simple functions, which await then return , perhaps with a try/catch block at most.
The await expression causes async function execution to pause until a promise is settled (that is, fulfilled or rejected), and to resume execution of the async function after fulfillment. When resumed, the value of the await expression is that of the fulfilled promise.
then() Promises and async/await are interchangeable. Whenever you see an await -statement, you can replace it with a . then() .
An easy function to use and understand for some async replace :
async function replaceAsync(str, regex, asyncFn) { const promises = []; str.replace(regex, (match, ...args) => { const promise = asyncFn(match, ...args); promises.push(promise); }); const data = await Promise.all(promises); return str.replace(regex, () => data.shift()); }
It does the replace function twice so watch out if you do something heavy to process. For most usages though, it's pretty handy.
Use it like this:
replaceAsync(myString, /someregex/g, myAsyncFn) .then(replacedString => console.log(replacedString))
Or this:
const replacedString = await replaceAsync(myString, /someregex/g, myAsyncFn);
Don't forget that your myAsyncFn
has to return a promise.
An example of asyncFunction :
async function myAsyncFn(match) { // match is an url for example. const fetchedJson = await fetch(match).then(r => r.json()); return fetchedJson['date']; } function myAsyncFn(match) { // match is a file return new Promise((resolve, reject) => { fs.readFile(match, (err, data) => { if (err) return reject(err); resolve(data.toString()) }); }); }
The native replace
method does not deal with asynchronous callbacks, you cannot use it with a replacer that returns a promise.
We can however write our own replace
function that deals with promises:
async function(){ return string.replace(regex, async (match)=>{ let data = await someFunction(match) console.log(data); //gives correct data return data; }) } function replaceAsync(str, re, callback) { // http://es5.github.io/#x15.5.4.11 str = String(str); var parts = [], i = 0; if (Object.prototype.toString.call(re) == "[object RegExp]") { if (re.global) re.lastIndex = i; var m; while (m = re.exec(str)) { var args = m.concat([m.index, m.input]); parts.push(str.slice(i, m.index), callback.apply(null, args)); i = re.lastIndex; if (!re.global) break; // for non-global regexes only take the first match if (m[0].length == 0) re.lastIndex++; } } else { re = String(re); i = str.indexOf(re); parts.push(str.slice(0, i), callback.apply(null, [re, i, str])); i += re.length; } parts.push(str.slice(i)); return Promise.all(parts).then(function(strings) { return strings.join(""); }); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With