【问题标题】:Node.js script appears to be synchronous even though I would expect it to be asynchronous? [duplicate]Node.js 脚本似乎是同步的,即使我希望它是异步的? [复制]
【发布时间】:2018-04-29 21:01:31
【问题描述】:

我正在做一个 Node.js 练习(来自 Nodeschool.io),内容如下:

 # LEARN YOU THE NODE.JS FOR MUCH WIN!  

 ## JUGGLING ASYNC (Exercise 9 of 13)  

  This problem is the same as the previous problem (HTTP COLLECT) in that  
  you need to use http.get(). However, this time you will be provided with  
  three URLs as the first three command-line arguments.  

  You must collect the complete content provided to you by each of the URLs  
  and print it to the console (stdout). You don't need to print out the  
  length, just the data as a String; one line per URL. The catch is that you  
  must print them out in the same order as the URLs are provided to you as  
  command-line arguments.  

为了测试我的实现,我做了一个像这样的小 Flask 应用程序:

from flask import Flask
import time

app = Flask(__name__)


@app.route("/1")
def hello1():
    time.sleep(1)
    return "Hello 1! "


@app.route("/2")
def hello2():
    time.sleep(0.5)
    return "Hello 2!"


@app.route("/3")
def hello3():
    return "Hello 3!"

为了让我开始 Nodeschool 练习,我编写了以下 Javascript 代码 (jugglingAsync.js):

var http = require('http');
var bl = require('bl');

var handler = (response) => {
    response.pipe(bl(function (err, data) {
    if (err) {
        return console.error(err)
    }
    console.log(data.toString())
    }))
}

http.get(process.argv[2], handler)
http.get(process.argv[3], handler)
http.get(process.argv[4], handler)

但是,如果我运行此脚本,我会看到响应 1-3 以该顺序打印,而不是相反的顺序:

Kurts-MacBook-Pro:learnyounode kurtpeek$ node jugglingAsync.js http://localhost:5000/1 http://localhost:5000/2 http://localhost:5000/3
Hello 1! 
Hello 2!
Hello 3!

但是,如果这些命令是异步运行的,我实际上希望结果以相反的顺序打印。有人可以解释为什么不是这样吗?

【问题讨论】:

  • 我猜 time.sleep() 正在暂停所有其他路线。我认为 hello2 或 hello3 在 time.sleep 完成之前不会回答。
  • 我使用FLASK_APP=hello.py flask run 启动了 Flask 服务器,看起来与 Django 不同,开发服务器不会立即适应您在源代码中所做的更改;停止并重新运行它后,我确实经历了预期的等待时间。 (我后来添加了time.sleep 语句)。所以看起来问题毕竟是Javascript代码。我已经更新了我的问题以反映这一点。
  • 我还在想,虽然 time.sleep() 被调用,但其他路由没有响应。我认为您可以通过在一条路线上长时间睡眠(例如一分钟)并在浏览器内部尝试访问另一条路线来测试这一点。
  • 我试过了,但第二个视图在那一分钟内工作正常。据我了解,每个请求都在单独的线程中运行?
  • 我刚刚在本地环境中运行了您的代码,输出为:C:\Users\me>node test.js localhost:5000/1 localhost:5000/2 localhost:5000/3 Hello 3!你好2!你好 1!

标签: javascript python node.js flask


【解决方案1】:

事实证明Theodor B 是对的:默认情况下,Flask 的底层 Werkzeug 服务器运行在单线程中,一次只能处理一个请求。为了多线程运行,必须将threaded=True 传递给app.run()(参见http://werkzeug.pocoo.org/docs/0.14/serving/#werkzeug.serving.run_simple):

if __name__ == "__main__":
    app.run(threaded=True)

现在 Node.js 脚本打印出预期的输出:

Kurts-MacBook-Pro:learnyounode kurtpeek$ node jugglingAsync.js http://localhost:5000/1 http://localhost:5000/2 http://localhost:5000/3
Hello 3!
Hello 2!
Hello 1! 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-21
    • 2015-03-20
    • 2013-10-16
    • 1970-01-01
    • 2016-03-01
    相关资源
    最近更新 更多