Django
以下是一个 Django Celery 异步任务的示例:
首先,需要安装 Celery:
pip install celery
在项目的 settings.py 文件中配置 Celery:
CELERY_BROKER_URL = "redis://localhost:6379/0" # 指定消息队列使用 redis
CELERY_RESULT_BACKEND = "redis://localhost:6379/1" # 指定任务结果的存储位置
CELERY_TIMEZONE = "Asia/Shanghai" # 指定时区
CELERY_IMPORTS = (
"your_app.tasks", # tasks 是存放任务的文件夹名
)
接下来,在 your_app 文件夹中创建一个 tasks.py 文件,用于存放异步任务:
from celery import shared_task
@shared_task
def add(x, y):
return x + y
在视图函数中调用该任务:
from django.http import HttpResponse
from your_app.tasks import add
def my_view(request):
result = add.delay(2, 3) # 异步执行任务
return HttpResponse(result.id)
以上示例代码的作用是将两个数相加并返回结果。调用任务时使用了 delay() 方法,该方法会将任务发送到 Celery 的消息队列中,并立即返回一个 AsyncResult 对象,这个对象包含了任务的状态信息和结果。
需要注意的是,Celery 需要启动一个 worker 进程来处理任务,启动方式为:
celery -A proj worker --loglevel=info
-A 参数指定项目名称,worker 表示启动 worker 进程,–loglevel 参数指定日志等级。
代码启动Celery
在 Django 项目的 settings.py 文件中添加以下代码,配置 Celery 使用的消息代理和结果存储位置(这里仍然使用 Redis 数据库):
CELERY_BROKER_URL = 'redis://localhost:6379/0'
CELERY_RESULT_BACKEND = 'redis://localhost:6379/0'
同时,为了让 Django 应用程序能够识别 Celery 任务,还需在 init.py 文件中定义 Celery 实例:
import os
from celery import Celery
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
app = Celery('myproject')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()
上述代码中,config_from_object() 方法会将消息代理和结果存储位置配置到 Celery 实例对象中。而 autodiscover_tasks() 方法会自动发现所有已经注册的任务,并在 worker 进程中执行。
最后,在 Django 项目入口文件中启动 Celery worker 进程,例如:
from myproject import app
if __name__ == '__main__':
app.worker_main(['worker', '--loglevel=INFO'])
在上述代码中,通过使用 Celery 的 worker_main() 方法来启动 Celery 的 worker 进程。
当有任务被提交到 Celery 时,它们将被分配给 worker 进程执行。需要注意的是,任务必须在 Django 项目的上下文环境中运行,因此在定义任务函数时应该使用 @app.task 装饰器来确保任务能够正确执行。
Flask
在 Flask 中使用 Celery 可以实现异步任务处理和定时任务等功能。下面是一个简单的示例来说明如何在 Flask 中使用 Celery:
首先,需要安装Celery 包:
pip install Celery
然后,创建一个 Flask 应用程序和一个 Celery 实例,例如:
from flask import Flask
from celery import Celery
app = Flask(__name__)
app.config['CELERY_BROKER_URL'] = 'redis://localhost:6379/0'
app.config['CELERY_RESULT_BACKEND'] = 'redis://localhost:6379/0'
celery = Celery(app.name, broker=app.config['CELERY_BROKER_URL'])
celery.conf.update(app.config)
在上述代码中,CELERY_BROKER_URL 和 CELERY_RESULT_BACKEND 分别设置了 Celery 使用的消息代理和结果存储位置,这里使用的是 Redis 数据库。Celery 实例的 conf 属性也被设置为 Flask 应用程序的配置文件。
接下来,在 Flask 应用程序中定义一个视图函数,使用 Celery 异步执行任务,例如:
from flask import request
from mytasks import add # 导入自定义的任务
@app.route('/task')
def task():
x = int(request.args.get('x'))
y = int(request.args.get('y'))
result = add.delay(x, y) # 异步执行任务
return result.id
在上述代码中,使用 Celery 的 delay() 方法将任务提交到消息代理,并返回结果的 ID。该任务将运行于一个独立的 worker 进程中。
最后,在 Flask 应用程序的入口文件中启动 Celery worker 进程,例如:
from myapp import app, celery
if __name__ == '__main__':
with app.app_context():
celery.worker_main(['worker', '--loglevel=INFO'])
在上述代码中,使用 Flask 的 app_context() 方法进入应用程序的上下文环境,然后通过执行 celery.worker_main() 启动 Celery 的 worker 进程。
注意要把任务定义、Flask 实例、Celery 实例放在同一目录下或者将任务定义导入进来。具体实现还需要根据自己的需求进行相应的调整和配置。
Express
Async
async.parallel、async.waterfall、async.series和async.auto都是Async.js中提供的异步控制流模块,用于执行一系列的异步操作。
以下是它们的异同点:
async.parallel允许多个异步操作同时执行,不需要等待前一个异步操作完成。当所有异步操作都完成后,parallel会将结果以数组形式返回。而且每个异步操作之间是相互独立的。
async.waterfall有序地执行多个异步任务,每个异步任务的输出作为下一个异步任务的输入,因此前一次执行结果可以传递到下一次执行。最终结果由最后一个异步任务提供。
async.series顺序执行多个异步操作,即先执行第一个异步操作,待第一个异步操作完成后再执行第二个异步操作,依次类推,直到所有异步操作全部完成,然后返回结果。
async.auto根据依赖自动执行多个异步操作,并确保每个异步操作只在其所有前置操作完成之后才会执行。auto会通过依赖分析来确定各个异步操作之间的关系,以此实现今日按需调度。
总体来说,这些函数都旨在帮助我们更加有效地管理异步操作,并避免“回调地狱”等复杂问题的出现。不同的函数有着不同的使用场景,选择哪种方式取决于业务需求。
下面是几个使用Async.js中异步控制流模块的示例代码:
async.parallel 的例子
const async = require('async');
async.parallel([
function(callback) {
setTimeout(function() {
console.log('Task One');
callback(null, 1);
}, 2000);
},
function(callback) {
setTimeout(function() {
console.log('Task Two');
callback(null, 2);
}, 1000);
}
],
// optional callback
function(err, results) {
console.log(results);
});
上面的代码表示同时执行两个异步操作 Task One 和 Task Two ,分别需要2秒和1秒完成,最终返回它们的结果 [1, 2]。
async.waterfall 的例子
const async = require('async');
async.waterfall([
function(callback) {
callback(null, 'one', 'two');
},
function(arg1, arg2, callback) {
console.log(arg1, arg2);
callback(null, 'three');
},
function(arg1, callback) {
console.log(arg1);
callback(null, 'done');
}
], function (err, result) {
console.log(result);
});
上面的代码表示三个任务展开,第一个任务不需要异步操作并将两个参数传递给第二个任务;第二个任务打印出前两个参数,并将字符串“three”作为输出传递给第三个任务。 第三个任务打印“three”,然后以字符串“done”调用回调函数。
async.series 的例子
const async = require('async');
async.series([
function(callback) {
console.log('Task One');
callback(null, 'one');
},
function(callback) {
console.log('Task Two');
callback(null, 'two');
}
],
// optional callback
function(err, results) {
console.log(results);
});
上面代码表示顺序执行两个异步操作 Task One 和 Task Two ,最终输出它们的结果 [‘one’, ‘two’]。
async.auto 的例子
const async = require('async');
async.auto({
get_data: function(callback) {
console.log('Task One: get_data');
callback(null, 'data', 'converted to array');
},
make_folder: function(callback) {
console.log('Task Two: make_folder');
callback(null, 'folder');
},
write_file: ['get_data', 'make_folder', function(results, callback) {
console.log('Task Three: write_file');
console.log(results);
callback(null, 'filename');
}],
email_link: ['write_file', function(results, callback) {
console.log('Task Four: email_link');
console.log(results);
callback(null, {'file':results.write_file, 'email':'user@example.com'});
}]
}, function(err, results) {
console.log('Final callback: ',results);
});
上面的代码包含了一些有依赖关系的任务,如 make_folder 任务需要在 get_data 任务完成后才能执行,write_file 任务需要在 make_folder 和 get_data 都完成后才能执行。 最终任务 email_link 需要获取 write_file 的结果作为输入。 autoseries 等同于 auto,除了它以串行顺序执行 async 函数。 根据依赖自动执行多个异步函数,并确保每个异步函数只在其所有前置任务完成后才会执行。