Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javascript : Async/await in .replace

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.

like image 912
ritz078 Avatar asked Nov 10 '15 13:11

ritz078


People also ask

What is the alternative for async await?

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.

How does async await work in JavaScript?

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.

Can we replace promise with async await?

then() Promises and async/await are interchangeable. Whenever you see an await -statement, you can replace it with a . then() .


2 Answers

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())         });     }); } 
like image 176
Overcl9ck Avatar answered Sep 20 '22 22:09

Overcl9ck


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("");     }); } 
like image 26
Bergi Avatar answered Sep 19 '22 22:09

Bergi