1

I am trying to make a crawler, and as the data is not showing in the page source, I can only execute the javascript with the web driver and get the response, and then do the data analysis. The script is simplified, like this, use Promise.

var res = ""

function f1() {
    p = window.Promise
    a = p.resolve(5).then(function(value) {
        console.log(value)
        res = value
        return res
    })
    return a
}
console.log(f1()) // Promise object
console.log("result = ", res) // res is empty

My program is like this, writing with c#:

 public void GetParameters(string url)
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl(url);
            IJavaScriptExecutor js = driver as IJavaScriptExecutor;
            string script = readFile(@"C:\myscript.js", Encoding.UTF8).TrimEnd(); // The script is a bit long, so I save it to a local file.
            var json = js.ExecuteScript(script);
            Console.WriteLine("Get the return value");
            Console.WriteLine(json);
            driver.Close();
        }

I want to get the value, and I know then always return Promise object, so I define a variable, and want to store the value to it. But seems that, the Promise is executed asynchronous, so the res always be empty.

OK, I'm writing a crawler, and use Selenium to get the response from the server (Selenium.webdriver can open a web browser, and then execute script), I need get the result, as it will use by another program. So, I can not just add another .then, just output the value. Maybe I can save to a local file, and then read it, but I think it is inefficient.

Anyone can help?

QLG
  • 121
  • 5
  • You're using promises incorrectly. `f1().then(res => console.log('result=', res))`. See [mdn](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) for more. – royhowie Dec 16 '16 at 04:06
  • Maybe you are looking for [`executeAsyncScript` instead](https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/JavascriptExecutor.html#executeAsyncScript-java.lang.String-java.lang.Object...-)? (this is the Java documentation but there must be something similar for C#). `executeScript` appears to be for synchronous JavaScript which you apparently do not have. If I understand your question correctly, you don't have control over the JavaScript? But yes, promises are asynchronous. – Felix Kling Dec 16 '16 at 04:38
  • year, there is also a function executeAsyncScript in C#, but when I call it, an error will be thrown said that cannot get the result in 0 seconds, then I set the timeout time to 5 seconds(5 seconds is enough to get the response), but it also said that cannot get the result in 5 second ... Then I give up this way, and I find another way to get the result. I try to create an element in the page, and set the text to the return value. After that, search for the element I created. It works! Anyway, thanks for you suggestions. – QLG Dec 16 '16 at 09:42

2 Answers2

2

When you try to log the global res, the result hasn't been computed yet. When using Promises, you have to get the result asynchronously, using .then, like this:

f1().then(res => console.log("result =", res));
qxz
  • 3,814
  • 1
  • 14
  • 29
  • This question was obviously a duplicate. Why answer it? Comment (since the answer is so simple) and then search for duplicate to flag. – royhowie Dec 16 '16 at 04:08
  • Like this? http://stackoverflow.com/questions/31909460/javascript-promise-return, oh, come one, I have search it before, and my problem is not same as that, because the "get the value" and "use the value" is two part, and also in two different process. – QLG Dec 16 '16 at 04:23
  • Can you edit your question to include the current code you're working on with Selenium? – qxz Dec 16 '16 at 04:25
2

Try this You're using promises incorrectly.

f1().then(res => console.log('result=', res)).

Sathyanarayanan
  • 432
  • 3
  • 7