2015-06-24 3 views
1

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

Я использую Bluebird для обещаний, с Sequelize (SQL ORM).

Пример кода:

db.sync().then(function() { 
    // When DB ready, insert some posts 
    return [ 
     BlogPost.create(), 
     BlogPost.create() 
    ]; 
}).spread(function (post1, post2) { 
    // Once posts inserted, add some comments 
    return [ 
     post1.createComment({ content: 'Hi - on post 1' }), 
     post2.createComment({ content: 'Hi - on post 2' }) 
    ]; 
}).spread(function (post1, post2) { // THE PROBLEM: Want posts here, not comments 
    // Do more with posts after comments added, e.g. add tags to the posts 

    // Can't do that in the above as something needs to wait for 
    // comment creation to succeed successfully somewhere. 

    // Want to wait on Comments promise, but keep using Posts promise result 
}); 

Лучшее решение, которое я до сих пор является:

db.sync().then(function() { 
    // When DB ready, insert some posts 
    return [ 
     BlogPost.create(), 
     BlogPost.create() 
    ]; 
}).spread(function (post1, post2) { 
    // Once posts inserted, add some comments 
    return Promise.all([ 
     post1.createComment({ content: 'Hi - on post 1' }), 
     post2.createComment({ content: 'Hi - on post 2' }) 
    ]).then(function() { 
     // Extra nested promise resolution to pull in the previous results 
     return [post1, post2]; 
    }); 
}).spread(function (post1, post2) { 
    // Do things with both posts 
}); 

Конечно, есть лучший способ хотя? Bluebird имеет .tap(), который довольно близок, но не выполняет функцию spread(), и я не могу найти простой способ объединения.

ответ

0

После более внимательного рассмотрения, я нашел лучший ответ до сих пор (с 0 обещание вложенности):

db.sync().then(function() { 
    // When DB ready, insert some posts 
    return [ 
     BlogPost.create(), 
     BlogPost.create() 
    ]; 
}).all().tap(function (posts) { 
    // Once posts inserted, add some comments 
    return [ 
     posts[0].createComment({ content: 'Hi - on post 1' }), 
     posts[1].createComment({ content: 'Hi - on post 2' }) 
    ] 
}).spread(function (post1, post2) { 
    // Do things with both posts 
}); 

Обратите внимание на .all() до крана: это обеспечивает результат первого, то() развернут правильно, прежде чем будет достигнут кран(), и позволяет использовать кран в качестве нормальный. Все еще не дает вам поддержку spread(), но это достаточно близко.

1

Я закрыл это, но затем снова открыл, так как ваша проблема намного более конкретна, чем общая. Make sure your read this question and answers по общей проблеме.

Для конкретного контекста одной акции, выше - вы можете использовать .return с Bluebird переопределять возвращаемое значение:

db.sync().then(function() { 
    ... 
}).spread(function (post1, post2) { 
    return Promise.all([ 
     post1.createComment({ content: 'Hi - on post 1' }), 
     post2.createComment({ content: 'Hi - on post 2' }) 
    ]).return([post1, post2]); // use .return here 
}).spread(function (post1, post2) { comments 
    // posts here 
}); 
+0

Вариант этого не распространяется. Используя '.then (function (posts) {...}' вы можете 'возвращать Promise.all (...). Return (posts)' без необходимости отбрасывать исходные данные. Конечно, вам нужно будет сделать 'posts [0] .createComment (...)' и 'posts [1] .createComment (...)', но, возможно, это меньшее зло. Ничего особенного - по крайней мере, не с известным небольшим количеством сообщения. –

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