2013-11-21 3 views
1

Мне интересно, как выполнить обмен значениями между «цепными звеньями» в обещаниях Q без полного искажения симпатичной идиомы обещаний.Использовать значение с первого обещания в более поздней цепочке ссылок

Я использую Q, чтобы сделать некоторую логику баз данных mongo. Моя GET конечная логика выглядит великолепно:

return Q.ninvoke(this.db, 'collection', 'namespace') 
    .then(function(namespaceCollection){ 
    return Q.ninvoke(namespaceCollection,'findOne',{"name":name}) 
    }).then(function(queryResults){ 
    if(!queryResults){ 
     throw new providerErrors.NotFound(); 
     return 
    } 
    return queryResults; 
    },function(err){ 
     throw new providerErrors.BadRequest(); 
    });; 

Применяя тот же шаблон для моей вставки конечной точки, однако, я столкнулся с проблемой. Я должен использовать коллекцию вернулся из первого обещания, тот, который получает коллекцию от объекта БД, чтобы сохранить значение обратно вниз:

return Q.ninvoke(this.db,'collection','namespace') 
    .then(function(namespaceCollection){ 
    return Q.ninvoke(namespaceCollection,findOne,{"name":namespace.name}); 
    }) 
    .then(function(foundNamespace){ 
    if(namespace){ 
     throw new providerErrors.Conflict(); 
     return 
    } 
    //This is a new namespace object, give it a datetime and then 
    //let's save it! 
    namespace.createDate = new Date(); 
    }) 
    .then(function(namespaceToSave){ 
    //uhoh! no collection in scope down here, just the value to persist! 
    }) 

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

+0

точный дубликат [Как получить доступ к предыдущим результатам обещание в .then() цепи?] (Http://stackoverflow.com/questions/28250680/how-do-i-access-previous-promise -results-in-a-then-chain) – Bergi

ответ

1

Как только вы очистите имя переменной, вы можете просто объявить что-то в области видимости до первого Q.ninvoke. В первом обратном вызове присвойте его значению CB, затем используйте его в третьем пространстве имен.

var namespaceCollection = null; 
return Q.ninvoke(this.db,'collection','namespace') 
    .then(function(namespaceCol){ 
    namespaceCollection = namespaceCol; 
    return Q.ninvoke(namespaceCollection,findOne,{"name": namespace.name}); 
    }) 
    .then(function(foundNamespace){ 
    if(!foundNamespace){ 
     throw new providerErrors.Conflict(); 
     return 
    } 
    //This is a new namespace object, give it a datetime and then 
    //let's save it! 
    namespace.createDate = new Date(); 
    }) 
    .then(function(namespaceToSave){ 
    // namespaceCollection is now available! 
    }) 
+0

И эти значения были бы гарантированы набором последовательности обещаний? Это круто. Не нужно явно указывать в цепочке? – DeaconDesperado

+0

Q.all, как вы заметили, работает одновременно. Сама цепочка является чисто последовательной. –

1

Работает лучше всего, чтобы уловить значение, необходимое для последующих шагов в закрытии. Обещания могут гнездиться в обработчиках. Последовательность сохраняется в then, даже в и из вложенных цепей, возвращая обещание от обработчика.

return Q.ninvoke(this.db,'collection','namespace') 
    .then(function(namespaceCollection){ 
    return Q.ninvoke(namespaceCollection,'findOne',{"name":namespace.name}); 
    .then(function(foundNamespace){ 
     return // presumably returning a promise for the namespace 
      // to save here, otherwise, `then` chaining is unnecessary 
    }) 
    .then(function(namespaceToSave){ 
     // namespaceCollection is in scope 
    }) 
    }) 

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

  • Нет связанных вопросов^_^