2016-01-07 2 views
1

Я новичок в этом q материалах, и я нахожу это довольно удивительным, но есть кое-что, что я до сих пор не могу понять.Именованные обещают результаты с q.all в NodeJS

Мне удалось выполнить некоторые комбинированные обещания с q.all, пройдя q.all массив обещаний. Что-то вроде этого ..

var promises = [promiseOne(), promiseTwo()]; 
q.all(promises).then(function (results) { 
    res.send(results); 
}); 

Дело в том, что я на самом деле хочу, чтобы эти обещания быть названы, так что я не должен полагаться в порядке обещаний.

Я где-то читал, что вы можете передать объект q.all, чтобы получить результаты. Так что было бы что-то вроде этого:

var promises = { promiseOne: promiseOne(), promiseTwo: promiseTwo() } 
q.all(promises).then(function(results){ 
    res.send(results); 
}); 

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

{ 
    promiseOne: { 
     source: {} 
    }, 
    promiseTwo: { 
     source: {} 
    } 
} 

Так как бы вы идти о получении названных результатов от q.all?

Следует отметить, что количество обещаний, которое у меня будет в массиве promises, не фиксируется, поскольку я получаю это от параметра GET, отправленного пользователем к моей функции.

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

+0

Я не думаю, что вы можете передать объект как вход в 'Q.all', и результат' Q.all' будет массивом всегда – thefourtheye

+0

@thefourtheye Вот где я нашел этот http: // блог. 500tech.com/really-you-can-do-that-with-promises/ В случае № 2 он, кажется, делает это (не говоря, что это надежный ресурс). Кроме того, в Angular docs для q указано, что обещаниями может быть объект https://docs.angularjs.org/api/ng/service/$q. Не уверен, что q угловой JS тот же, что и Node. – lascort

+0

В документации [Q.js] (https://github.com/kriskowal/q/wiki/API-Reference) не указано, что 'Q.all()' будет принимать объект вместо массива. В качестве обходного пути я бы предложил, чтобы вы нашли способ включить требуемое имя как часть значения, с которым разрешено каждое обещание. –

ответ

3

Вот еще один способ написать код Roamer написал с функциональностью, которую вы запросили (вернуть объект):

Q.props = obj => { 
    const ps = Q.all(Object.keys(obj).map(x => Q.all([x, obj[x]]))); 
    return ps.then(x => x.reduce((p, c) => {p[c[0]] = c[1]; return p } , {})); 
}; 

Который позволит вам сделать:

Q.props(promises).then(o => { 
    o.promiseOne 
}); 

Хотя вам следует использовать Блюберд, если вы хотите, чтобы все эти вспомогательные функции.

+0

Ницца! Не знал о синей птице! Любые недостатки использования bluebird против q? – lascort

+0

@ lascort это новая библиотека - так есть. Q имеет более читаемый источник. Вот и все. –

+0

Отлично! Просто он работал с синей птицей! Спасибо вам за удивительность. Я не думаю, что принять этот ответ хорошо, поскольку на самом деле он не предлагает синюю птицу. Но если вы опубликуете ответ, то зеленый материал будет вашим. – lascort

1

Q.js появляется не предлагать Q.all(object), поэтому вам нужно будет сопоставить объект в массив, прежде чем перейти к Q.all()

Что-то вроде этого будет многоразовым и удобно:

Q.allObj = function (obj) { 
    var array = Object.keys(obj).map(function(key, i) { 
     try { 
      //expect a promise 
      return obj[key].then(function(value) { 
       return {key: key, value: value}; 
      }); 
     } 
     catch(e) { 
      // whoops it was a value 
      return {key: key, value: obj[key]}; 
     } 
    }); 
    return Q.all(array); 
}; 

Использование в качестве следует следующим образом:

Q.allObj(myObj).then(function(results) { 
    results.forEach(function(obj) { 
     var name = obj.key; 
     var value = obj.value; 
     ... 
    }); 
}); 
Смежные вопросы