2016-11-22 2 views
0

Я пытаюсь использовать обещания для выполнения цикла внутри цикла. Я хочу, чтобы внутренний цикл завершил свою итерацию, а затем внешняя петля должна итерации.Вложенные Promise.map() не возвращают никакого результата

, например: -

arr1 = [1,2,3,4]; 
arr2 = [5,6,7,8]; 

loopOfArr1{ 
    loopOfArr2{ 
     //functionality 
    } 
} 

Я хочу, чтобы для каждого значения arr1, петля arr2 должны получить казнены. и это будет как синхронизация цикла, так и синхронизация.

Вот мой код, используя обещания: -

exports.getAtpagesWeights = function(atpagesDataArray,selectedTagsIds, taggings, callback){ 
    var atpageData, forHubCount; 
    return Promise.map(selectedTagsIds, function(tag, index, count){ 
     return Promise.map(taggings, function(tagging, index, count){ 
      return new Promise(function(resolve, reject){ 
       var atpageArray = _.filter(atpagesDataArray, function(item){ 
        if(tagging.taggable_id == item.id && tagging.tag_id == tag){ 
         item = item.toObject(); 
         item.rank_weight = tagging.atpages_weight; 
         resolve(item); 
        } 
       }) 
      }) 
     })  
    }).then(function(result){ 
     console.log(result); 
     callback(null, result); 
    }).catch(function(error){ 
     callback(error, null); 
    }) 
} 

Но когда я проверить журнал, ничего не печатается, может кто-нибудь сказать, где я буду неправильно, или есть лучший подход?

+1

Я не вижу ничего асинхронного кода. Что вы используете для обещаний? Кроме того, обещания и обратные вызовы не очень хорошо сочетаются. Избегайте их смешивания. – Tomalak

+0

поэтому, если я использую forEach вместо обещания, как я смогу получить полученный массив, можете ли вы, пожалуйста, поддержать это с помощью быстрого примера? –

+0

Не зная, что такое входы и какой вывод вы пытаетесь построить. Но здесь нет ничего асинхронного. Забудьте обратные вызовы. Забудьте обещания. Брось все это. Напишите простую функцию, которая запускает цикл по своим параметрам, вычисляет значение и возвращает это значение. – Tomalak

ответ

2

В меру моего понимания вашего кода, вы хотите что-то так просто, как это:

exports.getAtpagesWeights = function (atpagesData, selectedTagIds, taggings) { 
    var atpagesIndex = {}, 
     atpagesWeights = atpagesData.map(item => { 
      var weighted = item.toObject(); 
      weighted.rank_weight = null; 
      atpagesIndex[item.id] = weighted; 
      return weighted; 
     }); 

    taggings.filter(t => selectedTagIds.includes(t.id)).forEach(t => { 
     atpagesIndex[t.taggable_id].rank_weight = t.atpages_weight; 
    }); 

    return atpagesWeights; 
}; 

Это возвращает плоский массив объектов, непосредственно полученных из atpagesData элементов, с rank_weight добавляемые для выбранных.

Как правило, существуют асинхронные обратные вызовы продолжения для одной цели и одной цели: для работы с асинхронными операциями.

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

Если ваш код не имеет асинхронных путей (и ваш пример кода не похож на него), то вам не нужен параметр callback, и вам также не нужны никакие обещания. Будь проще.

+0

Эй, ваш ответ довольно четкий и понятный, но при использовании кода, который вы предоставили, я получаю нулевое значение для ключа rank_weight в массиве. –

+1

Это не работает должным образом, неудивительно, учитывая тот факт, что вы не предоставили образец ввода или желаемый результат, ни какое-либо объяснение, что ваш код предполагается делать концептуально. Итак ... Так же, как я проанализировал ваш код, чтобы придумать (вероятно) упрощение, теперь ваша очередь анализировать мой код и понимать его и применять принципы к вашей проблеме. – Tomalak

+0

"* Обратные вызовы существуют для одной цели и одной цели: для работы с асинхронными операциями *" - нет. Код в вашем собственном ответе доказывает, что вы ошибаетесь. Оставьте обратные вызовы из картинки и скажите, что обещания предназначены только для асинхронных операций, и вы получите мой прогноз. – Bergi

1

1) Подробнее о методе _.filter, ваше использование не является неправильным

2) Последнее обещание не решить, а не отвергать, поэтому консоль печати ничего

3) вместо того, чтобы эта конструкция (если это не promisification)

return new Promise(function(resolve, reject){ 
    resolve(somthing) 
}) 

лучше использовать эту конструкцию

return Promise.resolve() 
    .then(function(){ 
     return somthing; 
    }) 

4) Я добавляю некоторую элегантность к вашему коду

exports.getAtpagesWeights = function(atpagesDataArray, selectedTagsIds, taggings, callback){ 
    var atpageData, forHubCount; 
    return Promise.map(selectedTagsIds, function(tag, index, count){ 
     return Promise.resolve() 
      .then(function() { 
       return Promise.filter(taggings, function(tagging) { 
        return tagging.tag_id === tag; 
       }) 
      }) 
      .then(function(taggings) { 
       return Promise.filter(atpagesDataArray, function(item) { 
        return _.chain(taggings) 
         .map('taggable_id') 
         .includes(item.id) 
         .value(); 
       }); 
      }) 
      .then(function(atpagesDataArray) { 
       return Promise.map(atpagesDataArray, function(item) { 
        item = item.toObject(); 
        item.rank_weight = _.chain(taggings) 
         .find({taggable_id: item.id}) 
         .get('atpages_weight') 
         .value(); 
        return item; 
       }); 

      }) 
      .value(); 
     })  
    }) 
    .then(function(result){ 
     console.log(result); 
     callback(null, result); 
    }) 
    .catch(function(error){ 
     callback(error, null); 
    }) 
} 
+0

Похоже, вы добавили еще одну связку бессмысленных обещаний ... – Bergi

+0

@Bergi i сделал код более читабельным и детерминированным. Некоторые обещания истинно бессмысленны, но я сделал их особыми для автора, например, – stasovlas

+0

ОК, элегантность субъективна (я бы нашел более сжатый код намного лучше), но я полностью согласен с вашими тремя первыми очками – Bergi

Смежные вопросы