NodeJS - 如何使 forEach 和 for 循环函数顺序
Posted
技术标签:
【中文标题】NodeJS - 如何使 forEach 和 for 循环函数顺序【英文标题】:NodeJS - how to make forEach and for loop functions sequential 【发布时间】:2018-01-20 12:32:01 【问题描述】:server.queue.forEach(function(q)
YTDL.getInfo(q, (error, info) =>
console.log(info["title"]);
message.reply('"' + info["title"] + '"');
);
);
for (var i = 0; i < server.queue.length; i++)
YTDL.getInfo(server.queue[i], (error, info) =>
console.log(info["title"]);
message.reply('"' + info["title"] + '"');
);
我正在使用 Node.js 为名为 Discord 的 VoIP 创建一个音乐机器人,每当执行上述任一循环时,它们都会以随机顺序打印。如何使它们按顺序打印(server.queue[0]、server.queue[1]、server.queue[2]...)?
YTDL
是一个名为 ytdl-core 的包,它可以下载 YouTube 视频并使用视频链接显示视频标题等信息。 server.queue
是一组 YouTube 视频链接。
【问题讨论】:
【参考方案1】:简单地说:
1) 安装:npm i --save async
2) 和代码:
const async = require('async');
async.eachSeries(
server.queue,
(q, next) =>
YTDL.getInfo(q, (error, info) =>
console.log(info["title"]);
message.reply('"' + info["title"] + '"');
next();
);
);
for..loop
不是解决异步问题的好方法 - 它会调用它们并运行 for 循环之后的下一条语句
【讨论】:
【参考方案2】:如果你不想使用async
库,你可以像这样使用Promise.all
const youtubeData = [];
for (var i = 0; i < server.queue.length; i++)
youtubeData.push(YTDL.getInfo(server.queue[i]));
Promise.all(youtubeData).then((values) =>
// These values will be in the order in which they are called.
);
请注意,Promise.all
将等待所有查询完成或在一个请求失败时拒绝所有查询。查看您的用例并进行相应选择。
根据库,如果没有提供回调,它会返回承诺
ytdl.getInfo(url, [options], [callback(err, info)])
如果您只想从视频中获取元信息,请使用此选项。如果回调 没有给出,返回一个承诺。
【讨论】:
【参考方案3】:我一直在努力解决这个问题以找到最佳解决方案,直到我发现了 ECMA6 中表示的内置 yield
功能。因此,使用gen-run
库,您可以执行以下操作:
let run = require('gen-run');
function notSequential()
for (let i = 0; i < 3; i++)
f(i * 1000);
console.log("it won't print after for loop");
function sequential()
run(function*()
for (let i = 0; i < 3; i++)
yield changedF(i * 1000);
console.log("it will print after for loop");
);
function f(time)
setTimeout(function()
console.log(time);
, time);
function changedF(time)
return function (callback)
setTimeout(function()
console.log(time);
callback();
, time);
notSequential();
for 循环后不会打印 0 1000 2000
sequential();
0 1000 2000 它将在 for 循环后打印
【讨论】:
以上是关于NodeJS - 如何使 forEach 和 for 循环函数顺序的主要内容,如果未能解决你的问题,请参考以下文章