Asynchronous load inside a replace function

I am working with replacements in Javascript. I did something like this:

var replacedText = originalText.replace(regex, function(value, i) { 
    return value + 'some_additional_data';
});

return replacedText;

      

But now I need to load the HTML template inside the replace method. The load method is called like this:

res.render(location, json, function(error, html) {
    //i have the html loaded with my json data
});

      

I need to load it inside the replace method, but I cannot do that:

var replacedText = originalText.replace(media, function(value, i) {
    var json = buildJSON(value);
    res.render(location, json, function(error, html) {
        //how could i return the "html" object for the replace function?
    });
});

      

I tried something like this, but it didn't work:

var replacedText = originalText.replace(media, function(value, i) {
    var json = buildJSON(value);
    return res.render(location, json, function(error, html) {
        return html;
    });
});

      

Any help would be appreciated Many thanks in advance

+3


source to share


2 answers


If you have a callback that requires a synchronous return value, you cannot use an asynchronous operation inside that callback to get that value. The async operation (by definition) will complete some time AFTER the callback returns, so the results of the async operation are simply not available to return from the callback, and there is no way to make JS wait for the async operation.

I'm not sure exactly what your code is trying to do, but from what you said, it sounds like you want to load an HTML template and use it in a replace operation. There are several ways to approach this problem.



For example, you can do this with two passes.

  • The first pass doesn't actually change your string, instead it just creates a list of required templates.

  • Then you download all the templates in this list.

  • Then, when all the templates you need are loaded, you can perform your replacement using the templates already loaded to perform your planned synchronous replacement.

+4


source


No, replace

only supports synchronous callbacks. However, there is a generic function that takes a callback that gives promises and returns a promise for the string with all the replacements made:



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("");
    });
}

      

+6


source







All Articles