Javascript 在继续for循环之前等待异步执行

Javascript 在继续for循环之前等待异步执行,javascript,node.js,asynchronous,promise,async-await,Javascript,Node.js,Asynchronous,Promise,Async Await,我想找到解决这个问题的办法。我们需要在打印完成之前打印5星号* let arr = [1, 2, 3, 4, 5]; for (let i = 0; i < arr.length; i++) { delay(); console.log('finished'); } function delay() { setTimeout(() => { console.log('*'); }, 1000) } 实现目标的其他方式有哪些?我想最低

我想找到解决这个问题的办法。我们需要在打印完成之前打印5星号*

let arr = [1, 2, 3, 4, 5];

for (let i = 0; i < arr.length; i++) {
    delay();
    console.log('finished');
}

function delay() {
   setTimeout(() => {
        console.log('*');
    }, 1000)
}
实现目标的其他方式有哪些?我想最低限度地更改原始代码。我刚刚在node中开始异步编程,想知道可能的方法。 此外,任何指向我可以学习和实现各种怪癖和解决方法的资源的指针都将非常棒


谢谢

您喜欢这项工作吗

让arr=[1,2,3,4,5];
for(设i=0;i{
console.log(“*”)
},i*1000)

}
当您询问解决此问题的其他可能方法时。另一种方式也可以是:

let arr = [1, 2, 3, 4, 5];
let progress = 0;

function processArray() {
    for (let i = 0; i < arr.length; i++) {
        delay();    
    }  
}

function delay() {
   setTimeout(() => {
      console.log('*');
      progress++;

      if(progress === arg.length){
          console.log('finished');
      } 

   }, 1000)
}
让arr=[1,2,3,4,5];
让进度=0;
函数processArray(){
for(设i=0;i{
console.log('*');
进步++;
如果(进度===参数长度){
console.log('finished');
} 
}, 1000)
}
您还可以:

Array.from([1,2,3,4,5],x=>{setTimeout(()=>console.log('*')),x*1000})
还有一种方法:

function PA(parms) {
  this.id = parms.id;
  this.ai = undefined;
  if ("maxCount" in parms)
    this.maxCount = parms.maxCount;
  this.count = 0;
}
PA.objs = [];
PA.prototype.ms  = 1000;
PA.prototype.maxCount = 5;
PA.prototype.stop = function() {
      if (this.ai) {
        clearInterval(this.ai);
        this.ai = undefined;
      }
  };
PA.prototype.start = function() {
      if (this.ai) this.stop();
      this.ai = setInterval("PA.objs[" + id + "].rn()", this.ms);
  };
PA.prototype.rn = function() {
    console.log("*");
    if (this.count<this.maxCount) {
      this.count += 1;
    }
    else {
      console.log("done.");
      this.stop();
    }
  };

var id = 0;
PA.objs[id] = new PA({id: id});
PA.objs[id].start();
功能PA(parms){
this.id=parms.id;
this.ai=未定义;
如果(“最大计数”单位为帕姆)
this.maxCount=parms.maxCount;
此值为0.count;
}
PA.objs=[];
PA.prototype.ms=1000;
PA.prototype.maxCount=5;
PA.prototype.stop=函数(){
如果(this.ai){
clearInterval(this.ai);
this.ai=未定义;
}
};
PA.prototype.start=函数(){
如果(this.ai)this.stop();
this.ai=setInterval(“PA.objs[“+id+”].rn()”,this.ms);
};
PA.prototype.rn=函数(){
console.log(“*”);

如果(this.count当您使用计时器创建异步任务时,node.js的V8引擎会从堆栈中删除该任务,并等待计时器倒计时。因此,
console.log(“完成”)
是在开始时留在函数堆栈中的唯一任务,也是它首先在屏幕上打印的原因。即使计时器设置为0毫秒,它也会给出相同的结果

另一个解决方案如下所示

let arr = [1, 2, 3, 4, 5];
var counter = 1;
for (let i = 0; i < arr.length; i++) {
    delay();
}

function delay() {
   setTimeout(() => {
        console.log('*');
        counter += 1
        if (counter === arr.length)
            print();
    }, 1000)
}

function print(){
    console.log('finished');
}
让arr=[1,2,3,4,5];
var计数器=1;
for(设i=0;i{
console.log('*');
计数器+=1
如果(计数器===阵列长度)
打印();
}, 1000)
}
函数打印(){
console.log('finished');
}

由于延迟函数是异步的,在for循环中调用它将不会给出准确的结果。我认为您应该使用如下递归逻辑

let i = 0;
delay(i);

function delay(i) {
    if (i < 5) {
        setTimeout(() => {
            console.log('*');
            i++;
            delay(i);
        }, 1000)
    }
    else {
        console.log('finished');
    }
}
设i=0;
延迟(i);
功能延迟(一){
如果(i<5){
设置超时(()=>{
console.log('*');
i++;
延迟(i);
}, 1000)
}
否则{
console.log('finished');
}
}

解决问题的另一种方法是使用事件,如:

'use strict';
/* eslint-env node, es6 */

const EventEmitter = require('events');

/**
 * Count of running instances of the Event in delayedPrint.
 * @type {Number}
 */
let instances = 0;

/**
 * Prints message to console after delay milliseconds.
 *
 * @param  {String} message  - the message to print
 * @param  {Number} delay    - the number of milliseconds to delay printing
 */
const delayedPrint = (message, delay) => {
  const evt = new EventEmitter();

  message = (message || '').toString(); // assure message is a string
  delay = Number(delay) || 0; // assure delay is a number

  evt.on('start', () => { // uses setTimeout() to schedule an emit in the future
    instances++;
    setTimeout(() => {
      evt.emit('end');
    }, delay);
  });

  evt.on('end', () => { // what happens after delay milliseconds
    console.log(message);
    instances--;
    if (!instances) { // what happens after all running instances are complete.
      console.log('done');
    }
  });

  evt.emit('start'); // start delay
};

delayedPrint('It is now 10 seconds later!', 10 * 1000);
delayedPrint('It is now 5 seconds later!', 5 * 1000);
delayedPrint('It is now 1 second later!', 1 * 1000);

第二种方法不起作用吗?事实上是的,但我在某处被问到这个问题,没有人告诉我答案,因此我想知道其他方法:(
const delay=n=>newpromise(r=>setTimeout(r,n))
…然后你可以
等待延迟(1000)
在coursePlease的
异步
功能中,如果此答案解决了您的问题或回答了您的问题,请不要忘记将其标记为解决方案。
let i = 0;
delay(i);

function delay(i) {
    if (i < 5) {
        setTimeout(() => {
            console.log('*');
            i++;
            delay(i);
        }, 1000)
    }
    else {
        console.log('finished');
    }
}
'use strict';
/* eslint-env node, es6 */

const EventEmitter = require('events');

/**
 * Count of running instances of the Event in delayedPrint.
 * @type {Number}
 */
let instances = 0;

/**
 * Prints message to console after delay milliseconds.
 *
 * @param  {String} message  - the message to print
 * @param  {Number} delay    - the number of milliseconds to delay printing
 */
const delayedPrint = (message, delay) => {
  const evt = new EventEmitter();

  message = (message || '').toString(); // assure message is a string
  delay = Number(delay) || 0; // assure delay is a number

  evt.on('start', () => { // uses setTimeout() to schedule an emit in the future
    instances++;
    setTimeout(() => {
      evt.emit('end');
    }, delay);
  });

  evt.on('end', () => { // what happens after delay milliseconds
    console.log(message);
    instances--;
    if (!instances) { // what happens after all running instances are complete.
      console.log('done');
    }
  });

  evt.emit('start'); // start delay
};

delayedPrint('It is now 10 seconds later!', 10 * 1000);
delayedPrint('It is now 5 seconds later!', 5 * 1000);
delayedPrint('It is now 1 second later!', 1 * 1000);