Node.js ES5,如何在循环中使用承诺
假设命令长度=2 当我运行下面的函数device_execute_命令时。执行消息顺序为Node.js ES5,如何在循环中使用承诺,node.js,loops,promise,Node.js,Loops,Promise,假设命令长度=2 当我运行下面的函数device_execute_命令时。执行消息顺序为 finish one command finish one command has latest state? has latest state? 我预计: finish one command has latest state? finish one command has latest state? 代码 var设备执行命令=功能(命令arr){ //这是主回路 var i=0; 对于(i=0;i
finish one command
finish one command
has latest state?
has latest state?
我预计:
finish one command
has latest state?
finish one command
has latest state?
代码
var设备执行命令=功能(命令arr){
//这是主回路
var i=0;
对于(i=0;i
这是由于javascript的异步特性造成的。你想要的是一个接一个地履行承诺。这不能通过简单地在循环迭代中调用承诺来实现。实现这一点最简单的方法可能是使用bluebird
promise实现,它附带了许多用于承诺执行流控制的方法
例如,您的案例中的顺序执行可以通过以下方式实现:
const Promise = require('bluebird');
Promise.each(command_arr, function(command) {
return device_run_single_command(command).then(function(command) {
console.log();
console.log("finish one command");
console.log(command);
return is_device_has_latest_state(command);
}).then(function(command_with_condi) {
console.log();
console.log("has latest state?");
console.log(command_with_condi);
});
});
问题在于承诺是异步的,而SimpleFor循环不会暂停下一次迭代以等待上一次迭代完成 相反,您应该重新设计您的循环逻辑,并且只在上一次迭代完成后运行下一次迭代。例如,对于iLife,您可以这样做:
var device_execute_command = function(command_arr) {
var i = 0;
(function next() {
command_arr[i] && device_run_single_command(command_arr[i++]).then(function(command) {
console.log();
console.log("finish one command");
console.log(command);
return is_device_has_latest_state(command);
})
.then(function(command_with_condi) {
console.log();
console.log("has latest state?");
console.log(command_with_condi);
})
.then(next);
})();
}
如前所述,JavaScript承诺本质上是异步的。因此,在调用“device\u run\u single\u command(command)”函数之后,for循环将移动到下一个迭代。因此,可以观察到输出 在JavaScript中,这个问题可以通过各种机制来解决。Yerken和dfsq建议的方法肯定会奏效。随着async/await将来的到来,您甚至可以通过保持原来的for循环结构来解决这个问题。目前,可以使用babel编译器使用async/await
async function device_execute_command(command_arr) {
// This is the main loop
var i = 0;
for(i=0; i < command_arr.length; i++) {
var command = command_arr[i];
var command_id = command.command_id;
command = await device_run_single_command(command);
console.log();
console.log("finish one command");
console.log(command);
var command_with_condi = await is_device_has_latest_state(command);
console.log();
console.log("has latest state?");
console.log(command_with_condi);
}
}
异步功能设备执行命令(命令arr){
//这是主回路
var i=0;
对于(i=0;i
async function device_execute_command(command_arr) {
// This is the main loop
var i = 0;
for(i=0; i < command_arr.length; i++) {
var command = command_arr[i];
var command_id = command.command_id;
command = await device_run_single_command(command);
console.log();
console.log("finish one command");
console.log(command);
var command_with_condi = await is_device_has_latest_state(command);
console.log();
console.log("has latest state?");
console.log(command_with_condi);
}
}