Javascript Promise push-значение в массив (только из функции или снаружи?) - PullRequest
0 голосов
/ 30 июня 2018

У меня есть некоторые обещания и Promise.all:

array = [];


  var one = new Promise(function(resolve, reject) {
    // Do stuff
    setTimeout(function() {
      resolve('One Done');
      array.push('one');
    }, 5000);
  });


  var two = new Promise(function(resolve, reject) {
    // Do Stuff
    resolve('Two Done');
    array.push('two');
  });


  Promise.all(array).then(values => {
    console.log(values);
  });

Мы знаем, что это не работает, потому что array.push должен быть снаружи.

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

Желательно ли вызывать функцию из обещания так:

    function dosomething() {
        // does something
        array.push('something');
    }

  var mypromise = new Promise(function(resolve, reject) {
    dosomething();
    resolve('Did something');
  });

Или есть более рекомендуемый способ сделать это?

Ответы [ 3 ]

0 голосов
/ 30 июня 2018

Promise.all ожидает массив Promises. В вашем примере вы всегда помещаете string типы в массив. Это явно не сработает. В вашем первом примере вы хотите подтолкнуть сами обещания:

array = [];


  var one = new Promise(function(resolve, reject) {
    // Do stuff
    setTimeout(function() {
      resolve('One Done');
    }, 5000);
  });

  array.push(one);


  var two = new Promise(function(resolve, reject) {
    // Do Stuff
    resolve('Two Done');
  });

  array.push(two);

  Promise.all(array).then(values => {
    console.log(values);
  });

Пока массив содержит Promise объектов, Promise.all будет работать как положено.

0 голосов
/ 30 июня 2018

Обещание. Все ожидают массив обещаний и будут ждать, пока все обещания не будут выполнены, предоставляя вам результаты каждого Обещания или уловки, если какое-либо из них не выполнится.

Вы можете разрешить их с любым типом объекта, если вы хотите разрешить его с помощью не только строки, и вы можете впоследствии использовать результаты любым удобным для вас способом, чтобы вы могли не связываться с массивом из пообещайте и вместо этого разрешите «рабочий элемент» как единое целое и используйте все требуемые результаты после асинхронной оценки.

Это также (я думаю) сделает код чище и более управляемым.

Вместо этого вы можете попытаться сделать это:

   var valuesArray=[];

   var prom1 = new Promise(function(resolve, reject) {
        // Do stuff
        setTimeout(function() {
          resolve({ msg: 'One Done', data : 'one'});
          // array.push('one');
        }, 5000);
      });

    var prom2 = new Promise(function(resolve, reject) {
        // Do Stuff
        resolve({ msg: 'Two Done', data : 'two'});
        // array.push('two');
      });

   var promisesArray= [prom1,prom2]; 

   Promise.all(promisesArray).then(values => {
        // do stuff with values here
        console.log(values[0].msg);
        console.log(values[1].msg);
        valuesArray.push(values[0].data);
        valuesArray.push(values[0].data);
      });
0 голосов
/ 30 июня 2018

Я думаю, было бы яснее, если бы вы вызвали Promise.all с массивом Обещаний, с каждым Обещанием, разрешающим желаемое значение, без внешнего массива или push вообще:

var one = new Promise(function(resolve, reject) {
  // Do stuff
  setTimeout(function() {
    console.log('One Done')
    resolve('one');
  }, 1000);
});


var two = new Promise(function(resolve, reject) {
  // Do Stuff
  console.log('Two Done');
  resolve('two');
});


Promise.all([one, two]).then(arr => {
  console.log(arr);
});

Если вам нужны оба значения ('One Done' и 'one'), вы можете разрешить начальные обещания с помощью массива с обоими значениями, делая все, что вам нужно, с помощью 'One Done', а затем преобразуется с помощью 'one' в цепочку с массивом, созданным Promise.all:

const logAndReturn = ([logStr, finalResolveStr]) => {
  console.log(logStr);
  return finalResolveStr;
}
var one = new Promise(function(resolve, reject) {
  // Do stuff
  setTimeout(function() {
    resolve(['One Done', 'one']);
  }, 1000);
});


var two = new Promise(function(resolve, reject) {
  // Do Stuff
  resolve(['Two Done', 'two']);
});


Promise.all([
  one.then(logAndReturn),
  two.then(logAndReturn),
]).then(arr => {
  console.log(arr);
});
...