2016-09-01 1 views
1

У меня есть класс javascript, который в настоящее время выполняет несколько асинхронных вызовов, добавляет элементы в DOM, а затем вызывает обратный вызов пользователя. Что-то вроде этого:Как справиться с возвратом обещания, когда он уже запущен?

api.load = function() { 
    if (api.loading || api.loaded) 
     return; 

    api.loading = true; 
    makeAsyncCalls(); // will set api.loaded = true and run all pendingReady 
} 

api.ready = function(callback) { 
    if (!api.loaded) { 
     pendingReady.push(callback); 
    } 
    callback(someValue); 
} 

Это позволяет мне работать с несколькими вызовами в load и ready.

Я сейчас пытаюсь обновить это, чтобы использовать javascripts Promise. Приведенный выше код стал бы что-то вроде:

api.load = function() { 
    if (api.loaded) { 
     // callers attached .then() will still fire 
     return Promise.resolve(someValue); 
    } 

    if (api.loading) { 
     // Not sure how to handle this 
    } 

    api.loading = true; 
    return makeAsyncCalls(); // Which returns a Promise 
} 

Я не знаю, как обращаться случай, когда первый Promise начал, но еще не полностью загружен (разрешен в обещание речи). Единственный метод, о котором я могу думать, - это вернуть Promise, который завершает вызов setInterval, проверяя статус. Разумеется, есть лучший подход. Какие-либо предложения?

Чтобы это стало ясно. Каждый звонок до api.load должен возвращать Promise или thenable. Первый вызов инициирует асинхронные методы. Дальнейшие звонки должны возвращать Promise, который может разрешить или отклонить только ПОСЛЕ завершения начального Promise.

Цепочка обещаний будет работать только в том случае, если никакие значения не переданы обработчику успеха (первый .then() может не возвращать то же значение).

ответ

1

Сам по себе обещание может быть дублером для данных, полученных в асинхронном режиме ...

api.getAsyncResult = function() { 
    if (!api.asyncResult) { 
     api.asyncResult = makeAsyncCalls(); 
    } 
    return api.asyncResult; 
} 

Любое количество абонентов в любое время теперь может сказать:

api.getAsyncResult().then(function(result) { 
    // use result, which is whatever makeAsyncCalls's promise resolves to 
}); 

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

makeAsyncCalls() функции может поддерживать состояние api.loading флага, если вам это нужно. Нет необходимости в флагом api.loaded, если целью является только защита от избыточных вызовов (это делает проверка ложности в функции get).

+0

Мне потребовалось несколько раз, но я думаю, что понимаю. Поправьте меня, если я ошибаюсь (я думал о «то» в последовательности). Как только начальный 'Promise' разрешил, он поддерживает это состояние, поэтому любой вызов' then' автоматически вызывает обработчик успеха с помощью 'asyncResult'? Мне просто нужно сохранить и вернуть локальную копию. – Twifty

+0

У вас это точно. Он будет ссылаться на обработчик успеха независимо от того, что обещает makeAsyncCalls. – danh

+0

Спасибо. Чувствуйте себя как-то немым прямо сейчас. – Twifty

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

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