简体   繁体   中英

Return result from a javascript callback (node.js)

I know this question have been asked many times, but I can't make it work.

Here is my situation. I had a string called data , and I want to unshorten all the link inside that string.

Code:

 var Bypasser = require('node-bypasser'); var URI = require('urijs'); var data = 'multiple urls : http://example.com/foo http://example.com/bar'; var result = URI.withinString(data, function(url) { var unshortenedUrl = null; var w = new Bypasser(url); w.decrypt(function(err, res) { // How can I return res ? unshortenedUrl = res; }); // I know the w.descrypt function is a asynchronous function // so unshortenedUrl = null return unshortenedUrl; });

Let's me walk you through the code.

URI.withinString will match all the URLs in data , manipulate it and return the result.

You can view an example from URI.js docs

What I want to with these URLs is to unshorten all of them using node-passer.

This is from node-bypasser document :

var Bypasser = require('node-bypasser');

var w = new Bypasser('http://example.com/shortlink');
w.decrypt(function(err, result) {
    console.log('Decrypted: ' + result);
});

This is the result that I want multiple urls : http://example.com/foo_processed http://example.com/bar_processed

I created a notebook at tonicdev.com


Solution

var getUrlRegEx = new RegExp(
        "(^|[ \t\r\n])((ftp|http|https|gopher|mailto|news|nntp|telnet|wais|file|prospero|aim|webcal):(([A-Za-z0-9$_.+!*(),;/?:@&~=-])|%[A-Fa-f0-9]{2}){2,}(#([a-zA-Z0-9][a-zA-Z0-9$_.+!*(),;/?:@&~=%-]*))?([A-Za-z0-9$_+!*();/?:~-]))"
        , "g"
      );

      var urls = data.match(getUrlRegEx);

      async.forEachLimit(urls, 5, function (url, callback) {
        let w = new Bypasser(url);
        w.decrypt(function (err, res) {
          if (err == null && res != undefined) {
            data = data.replace(url, res);
            callback();
          }
        });
      }, function(err) {
        res.send(data);
      });

You don't really understand what callback is. The callback serves to allow asynchronous code to run without Javascript waiting for it. If you were less lazy and added some debug in your code:

console.log("Started parsing");
var result = URI.withinString(data, function(url) {
    console.log("URL parsed (or whatever)");
    var unshortenedUrl = null;

    var w = new Bypasser(url);
    w.decrypt(function(err, res) {
      // How can I return res ?
      unshortenedUrl = res;
    });
    // I know the w.descrypt function is a asynchronous function
    // so unshortenedUrl = null
    return unshortenedUrl;
});
console.log("Call to library over");

You would (most likely) see messages in this order:

Started parsing
Call to library over
URL parsed (or whatever)

The answer: Callback is not guaranteed to run before any code you execute after assigning it. You can't put data in your result variable because the data might not be fetched yet.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM