Использование обещания bluebird не работает в моем созданном примере - PullRequest
0 голосов
/ 07 февраля 2020

Я изучал и пытался понять Асинхронный javascript. После большого чтения и предложения использовать библиотеку bluebird, потому что я использую IE11, я попробовал это на простом примере, который я создал, но он не работает, как ожидалось. Я добавил settimeout в каждую функцию для симуляции асинхронности. Цель состоит в том, чтобы заполнить массивы, чтобы я мог console.log () значения массива, но это было безрезультатно. В моем promise.all я вызываю createNavigation (), который предполагает, что все мои массивы заполнены, но это не так. Кроме того, номера возвращаются для результатов в promise.all.
Что я делаю неправильно или неправильно? Почему мои массивы записываются на консоль в виде пробелов?

var cacheNavData = [];
var cacheSubNavData = [];
var cacheMegaMenuData = [];
var cacheCategoryMenuData = [];

getNavData();
getSubNavData();
getMegaMenuData();
getCategoryMenuData();

var promises = [
  getNavData(),getSubNavData(),getMegaMenuData(),getCategoryMenuData()
]

Promise.all(promises)
 .then(function(results){
 console.log(results)
 createNavigation()
})
function getNavData(){
   return setTimeout(function(){ 
    cacheNavData[0] = "Soup";
    cacheNavData[1] = "Sandwich";
    cacheNavData[2] = "Rice";  
   }, 3000);
 }

 function getSubNavData(){
   return setTimeout(function(){ 
    cacheSubNavData[0] = "Apple";
    cacheSubNavData[1] = "Beans";
    cacheSubNavData[2] = "Carrot";    
  }, 3000);

 }

 function getMegaMenuData(){
    return setTimeout(function(){ 
    cacheMegaMenuData[0] = "Donkey";
    cacheMegaMenuData[1] = "Eagle";
    cacheMegaMenuData[2] = "Frog";
 }, 3000);
}

function getCategoryMenuData(){
   return setTimeout(function(){ 
    cacheCategoryMenuData[0] = "Grapes";
    cacheCategoryMenuData[1] = "Hand";
    cacheCategoryMenuData[2] = "Igloo";    
   }, 3000);
 }

 function createNavigation(){
   console.log("All arrays have been populated.  Let's build the navigation.")

 }

 console.log(cacheNavData);
 console.log(cacheSubNavData);
 console.log(cacheMegaMenuData);
 console.log(cacheCategoryMenuData);

codepen

1 Ответ

3 голосов
/ 07 февраля 2020

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

function getNavData(){
   return new Promise(function(resolve) {
     setTimeout(function(){ 
      cacheNavData[0] = "Soup";
      cacheNavData[1] = "Sandwich";
      cacheNavData[2] = "Rice";

      resolve();
     }, 3000);
   });
 }

Если вы хотите, чтобы обещание вернуло данные, то вместо использования resolve() вы передаете данные, с которыми вы хотите разрешить, в качестве первого аргумента, например, resolve(cacheNavData).

Вы также не должны вести журнал консоли в конце вашего файла, так как эти массивы будут пустыми. Если вы хотите получить к ним доступ, вам следует вместо этого прочитать их из results, если вы решаете с полезной нагрузкой. Вы всегда можете использовать разброс массивов ES6 для распаковки результатов:

Promise.all(promises)
 .then(function(results){
  console.log(results);
  const [navData, subNavData, megaMenuData, categoryMenuData] = results;
  console.log(navData, subNavData, megaMenuData, categoryMenuData);
  createNavigation();
});

Это также означает, что вам не нужно объявлять глобальные массивы для всех ваших данных: ваши отдельные функции отвечают за передача заполненных массивов обратно в Promise.all.

См. пример проверки концепции:

var promises = [
  getNavData(),getSubNavData(),getMegaMenuData(),getCategoryMenuData()
]

Promise.all(promises)
 .then(function(results){
 console.log(results);
 const [navData, subNavData, megaMenuData, categoryMenuData] = results;
 console.log(navData, subNavData, megaMenuData, categoryMenuData);
 createNavigation();
})
function getNavData(){
   return new Promise(function(resolve) {
     setTimeout(function(){ 
      var cacheNavData = [];
      cacheNavData[0] = "Soup";
      cacheNavData[1] = "Sandwich";
      cacheNavData[2] = "Rice";
      
      resolve(cacheNavData);
     }, 3000);
   });
 }

 function getSubNavData(){
   return new Promise(function(resolve) {
     setTimeout(function(){
      var cacheSubNavData = [];
      cacheSubNavData[0] = "Apple";
      cacheSubNavData[1] = "Beans";
      cacheSubNavData[2] = "Carrot";
      
      resolve(cacheSubNavData);
    }, 3000);
   });
 }

 function getMegaMenuData(){
  return new Promise(function(resolve) {
    setTimeout(function(){ 
      var cacheMegaMenuData = [];
      cacheMegaMenuData[0] = "Donkey";
      cacheMegaMenuData[1] = "Eagle";
      cacheMegaMenuData[2] = "Frog";

      resolve(cacheMegaMenuData);
    }, 3000);
  });
}

function getCategoryMenuData(){
   return new Promise(function(resolve) {
     setTimeout(function(){ 
      var cacheCategoryMenuData = [];
      cacheCategoryMenuData[0] = "Grapes";
      cacheCategoryMenuData[1] = "Hand";
      cacheCategoryMenuData[2] = "Igloo"; 
      
      resolve(cacheCategoryMenuData);
     }, 3000);
    });
 }

 function createNavigation(){
   console.log("All arrays have been populated.  Let's build the navigation.")

 }
...