Ожидание завершения функции перед выполнением следующего шага - node js - PullRequest
1 голос
/ 10 февраля 2020

Я новичок в node js и в настоящее время узнаю об обещаниях и жду / asyn c. Я попробовал приведенный ниже код, но не смог понять, как заставить код ждать завершения функции hostping. Я также попробовал обещания, но не мог заставить его ждать.

var ping = require('ping');
var hoststatus
var hosts = ['google.com'];

async function test()
{
  var connected = await hostping(hosts);
  console.log('connected--------------', connected)
  connected.then(function(hoststatus) {
    console.log('hoststatus--------------', hoststatus)
    if (hoststatus == 1) {
      console.log('faaaaaaaail-------------')
    } else {
      console.log('passssssssssssssssss-----------')
    }
  });
}

async function hostping(hosts) {
  console.log('hosts-----------', hosts)
  await hosts.forEach(async function(host) {
    await ping.sys.probe(host, async function(isAlive) {
      var msg = isAlive ? 'host ' + host + ' is alive' : 'host ' + host + ' is dead';
      console.log(msg);
      if (isAlive == 'false') {
        hoststatus = 1
      }
    });
  });

  return hoststatus;
}

test()

Ответы [ 3 ]

1 голос
/ 10 февраля 2020

Это должно сделать то, что вы sh, мы используем for .. of l oop для итерации хостов по порядку.

В библиотеке ping также есть оболочка обещаний, которая позволяет пропускать используя обратные вызовы.

Вы также можете использовать Promise.all для выполнения всех пингов и тестов одновременно, но я не верю, что это то, что вы будете sh делать.

I включили hostpingVer2, который использует Promise.all, если вы хотите выполнить все эхо-запросы одновременно.

const ping = require('ping');
const hosts = ['google.com', 'amazon.com', 'itdoesntexist'];

async function test() {
    console.log('hosts: ', hosts)
    const results = await hostping(hosts);
    console.log('ping results: ', results);
}

async function hostping(hosts) {
    const results = [];
    for(let host of hosts) {
        let probeResult = await ping.promise.probe(host);
        results.push( { host, hoststatus: probeResult.alive ? 0: 1, alive: probeResult.alive } );
    }
    return results;
}

async function hostpingVer2(hosts) {
    const probeResults = await Promise.all(hosts.map(host => ping.promise.probe(host)));
    return probeResults.map(probeResult => { 
        return { host: probeResult.host, hoststatus: probeResult.alive ? 0: 1, alive: probeResult.alive } 
    });
}

test();
0 голосов
/ 10 февраля 2020

Чтобы сделать то, что вы хотите, вы должны использовать оболочку обещания ping, а также for..of, потому что forEach не работает с asyn c.

  • Функция hostping должна возвращать обещание, которого будет ждать тест.
  • Использовать для inside до l oop для хостов
  • использовать обещание Обертка ping и ожидание результата проверки
  • После проверки всех хостов определите общий статус

Ниже приведена модификация вашего кода, чтобы поток работал так, как вы ожидали:

const ping = require('ping');
const hosts = ['google.com', 'yahoo.com'];

async function test()
{
  const status = await hostping(hosts);

    if (status) {
        console.log('All hosts are alive');
    } else {
        console.log('Some/all hosts are dead');
    }

}

function hostping(hosts) {
    let status = true;
    return new Promise(async function(resolve, reject) {
      for (const host of hosts) {
        const res = await ping.promise.probe(host);
        var msg = `host ${host} is ${res.alive ? 'alive' : 'dead'}`;
        console.log(msg);
        if (!res.alive) { status = false; }
      }
        console.log('all host checks are done, resolving status');  
        resolve(status);
    });
}

test()

Если вам интересно узнать больше об asyn c, вот хорошие посты для чтения: https://www.coreycleary.me/why-does-async-await-in-a-foreach-not-actually-await/

https://itnext.io/javascript-promises-and-async-await-as-fast-as-possible-d7c8c8ff0abc

0 голосов
/ 10 февраля 2020

Вы используете await внутри forEach, который не должен работать, так как forEach не поддерживает обещания. Попробуйте изменить его на for..of или promise.all.

Кроме того, ваша функция зонда является стилем обратного вызова, который не возвращает обещание. Вам нужно обернуть его в обещание его дождаться.

function probe(host) {
  return new Promise((resolve, reject) => {
    ping.sys.probe(host, function (isAlive) {
      const msg = isAlive ? `host ${host} is alive` : `host ${host} is dead`;
      console.log(msg);
      resolve(isAlive);
    });
  });
}

async function hostping(hosts) {
  console.log("hosts-----------", hosts);
  for(const host of hosts) {
    // eslint-disable-next-line no-loop-func
    // eslint-disable-next-line no-await-in-loop
    const isAlive = await probe(host);
    if (isAlive === "false") {
      hoststatus = 1;
    }
  }
  return hoststatus;
}

...