gpt4 book ai didi

javascript - Node.js 什么时候使用异步有意义?

转载 作者:太空宇宙 更新时间:2023-11-04 02:42:48 25 4
gpt4 key购买 nike

我问自己什么时候与 Node.js 上的回调异步才有意义。当我处理 I/O、数据库和其他所有会阻塞的内容或代码的其余部分时,它是否有用?

例如,我有一个棋盘游戏的“布局”。它使用给定的 json 布局创建一个板实例。我知道使用异步进行 I/O(读取 json 布局文件)是有意义的,因为这会阻塞。例如 foreach 循环怎么样?它应该是异步的吗?底层 libuv 是否能从中获利?

这是带有异步库的版本:

/*jshint node: true, strict: true, globalstrict: true*/
"use strict";

// Imports
var fs = require('fs');
var async = require('async');
var Figure = require('../models/figure.js');
var Field = require('../models/field.js');
var Board = require('../models/board.js');

/**
* @param {Board} board
* @param {Array} template
* @param {string} owner
* @param {function(Error)} callback
*/
var createFigures = function (board, template, owner, callback) {
async.forEach(template, function (data, done) {
var figure = new Figure(owner, data.kind);
board.setFigure(data.x, data.y, figure);
done();
}, callback);
};

/**
* @param {Board} board
* @param {Array} fields
*/
var createFields = function (board, fields, callback) {
async.series([
function(done) {
for (var x = 0; x < board.getSize().x; x++) {
for (var y = 0; y < board.getSize().y; y++) {
var field = new Field(true, false);
board.setField(x, y, field);
}
}
done();
}, function(done) {
async.forEach(fields, function(data, iteratDone) {
var field = new Field(data.passable, data.corner);
board.setField(data.x, data.y, field);
iteratDone();
});
done();
}
], callback);
};

/**
* @param {{
* ....
*/
var build = function (layoutObj, callback) {
var board = new Board(layoutObj.name, layoutObj.size.x, layoutObj.size.y);

async.parallel([
function (done) {
createFigures(board, layoutObj.figures.white, Figure.owners.white, done);
},
function (done) {
createFigures(board, layoutObj.figures.black, Figure.owners.black, done);
},
function (done) {
createFields(board, layoutObj.fields, done);
}
],
function (err) {
callback(err, board);
}
);
};

/**
* @param string layoutPath
* @param {function(Error, )} callback
* @return {Board}
*/
var generateBoardWithLayout = function (layoutPath, callback) {
async.waterfall([
function(done) {
fs.stat(layoutPath, function(err, stats) {
done(null, stats);
});
}, function(stats, done) {
if (stats.isFile()) {
var jsonData = '';
fs.readFile(layoutPath, function(err, data) {
jsonData += data;
done(null, jsonData);
});
} else {
done(new Error("There is no '" + layoutPath + "'"));
}
}
], function(err, jsonData) {
build(JSON.parse(jsonData), callback);
});

};

module.exports.build = build;
module.exports.generateBoardWithLayout = generateBoardWithLayout;

这就是没有异步链接的版本

/*jshint node: true, strict: true, globalstrict: true*/
"use strict";

// Imports
var Figure = require('../models/figure.js');
var Field = require('../models/field.js');
var Board = require('../models/board.js');

/**
* @constructor
*/
function Layouter() {

}

Layouter.generateBoardWithLayout = function(layoutPath) {
var fs = require('fs');

var jsonData = fs.readFileSync(layoutPath);
if (!jsonData) {
throw new Error("There is no '" + layoutPath + "'");
}

return new Layouter().build(JSON.parse(jsonData));
};

Layouter.prototype = {

/**
* @param {{
* ....
*/
build: function (layoutObj) {
var board = new Board(layoutObj.name, layoutObj.size.x, layoutObj.size.y);

this.createFigures_(board, layoutObj.figures.white, Figure.owners.white);
this.createFigures_(board, layoutObj.figures.black, Figure.owners.black);
this.createFields_(board, layoutObj.fields);

return board;
},

/**
* @param {Board} board
* @param {Array} template
* @param {string} owner
* @private
*/
createFigures_: function (board, template, owner) {
template.forEach(function (data) {
var figure = new Figure(owner, data.kind);
board.setFigure(data.x, data.y, figure);
});
},

/**
* @param {Board} board
* @param {Array} fields
* @private
*/
createFields_: function (board, fields) {
for (var x = 0; x < board.getSize().x; x++) {
for (var y = 0; y < board.getSize().y; y++) {
var field = new Field(true, false);
board.setField(x, y, field);
}
}

fields.forEach(function (data) {
var field = new Field(data.passable, data.corner);
board.setField(data.x, data.y, field);
});
}

};

module.exports = Layouter;
module.exports.generateBoardWithLayout = Layouter.generateBoardWithLayout;

感谢您的宝贵时间!

您好,马库斯

最佳答案

我认为您错过了 Node.js 中异步性背后的想法。这不是关于使用 async 包(这只是可以与 Node 一起使用的 npm 包,而不是 Node 的内部包),而是关于以异步方式处理外部进程。例如当你查询数据库时,在等待结果的过程中你可能会做很多事情,就是这样。

如果您的代码不查询任何外部进程,但它是纯 JavaScript,那么对于单个进程,您无法直接从异步性中受益(Node.js 是单线程),您可以做的是将一些工作委托(delegate)给不同的进程并与其通信(请参阅 child_process.fork)。

关于javascript - Node.js 什么时候使用异步有意义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12182553/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com