Как устранить зависимость между действиями в магазине

My Store регистрирует 2 типа действий следующим образом:

Dispatcher.register(function (action) {
    switch (action.type) {
        case 'loadCar':
            loadCar();
            break;
        case 'loadTyres':
            loadTyres();
            break;
    }
})

как я могу гарантировать, что loadCar выполняется раньше loadTyres? Есть ли способ ждать этого зависимого метода без необходимости выполнять loadCar каждый раз, когда я хочу просто loadTyres?


person FranBran    schedule 20.02.2015    source источник
comment
Вы имеете в виду, что вам нужен waitFor: facebook.github.io/react/blog/2014/07/30/   -  person WiredPrairie    schedule 20.02.2015
comment
Я не думаю, что waitFor здесь подходит, так как он ожидает только обновления других хранилищ (что означает, что он ожидает обработки всех ожидающих отправки)   -  person FranBran    schedule 23.02.2015
comment
Вы можете просто иметь переменную состояния, которая отслеживает, была ли она загружена, или использовать обещание.   -  person WiredPrairie    schedule 23.02.2015
comment
даже с обещанием мне пришлось бы вызывать оба метода, не так ли...   -  person FranBran    schedule 23.02.2015
comment
carpromise.then(loadTyres()) например...?   -  person WiredPrairie    schedule 23.02.2015
comment
не могли бы вы привести полный пример в качестве ответа?   -  person FranBran    schedule 24.02.2015


Ответы (1)


Ниже приведен непроверенный шаблон, который вы можете попробовать. Возможно, вам потребуется начать отправку start loadcar, loadcar completed, например, чтобы завершить это (см. with-flux">здесь).

// pick your favorite Promise library
var Promise = require('bluebird'); 

Dispatcher.register(function (action) {
    switch (action.type) {
        case 'loadCar':
            // need to be async here
            loadCar(action.carId).then(function(car) {
                // this eventually returns                      
            });
            break;
        case 'loadTyres':
            // need to be async here
            loadTyres(action.carId).then(function(tyres) {

            })
            break;
    }
})

Вы также можете сохранить объект Promise и кэшировать его, чтобы он был «текущим» автомобилем, и тогда он не будет перезагружен (если вы не удалите его из массива).

var allCars = {};
function loadCar(id) {
    if(typeof allCars[id] === 'undefined') {
        allCars[id] = loadCarPromise(id);
    }
    return allCars[id];
}

Вы создадите функцию, которая возвращает обещание, которое будет разрешаться с учетом специфики car данных, которые вы загружаете. Вам нужно будет делать все, что вы обычно делаете там, но в конечном итоге вызовите обратные вызовы resolve или reject, чтобы правильно продолжить цепочку промисов.

function loadCarPromise(id) {
    return new Promise(function(resolve, reject) {
        // do whatever you do to get
        // the car
        // when it's done, call resolve
        // or reject if there is a failure.
        // ex:
        $.ajax({
            url: 'api/car/' + id,
            success: function(data) {
                resolve(data);
            },
            error: function(err) {
                reject(err);
            }
        });
    });
}

И, наконец, loadTyres будет использовать loadCar для внутреннего использования и разрешать себя только тогда, когда будут возвращены данные о шинах.

function loadTyres(carId) {
    // the car is always loaded first, then the tyres
    // but if using the cache, the car will be
    // returned immediately (although you won't need
    // to worry about that)
    return loadCar(carId).then(function(car) {
        return new Promise(function(resolve, reject) {
            // do something to load the tyres
            // with the car info that was returned
            resolve(/* tyres data */);          
        });
    });
}
person WiredPrairie    schedule 24.02.2015