#javascript #reactjs #redux-saga
#javascript #reactjs #redux-saga
Вопрос:
Итак, мне трудно понять, как преобразовать следующий пример для использования sagas, поскольку это не проблема асинхронности, связанная с ajax:
var dogBarkingBuffer = null;
// Fix up prefixing
window.AudioContext = window.AudioContext || window.webkitAudioContext;
var context = new AudioContext();
function loadDogSound(url) {
var request = new XMLHttpRequest();
request.open('GET', url, true);
request.responseType = 'arraybuffer';
// Decode asynchronously
request.onload = function() {
context.decodeAudioData(request.response, function(buffer) {
dogBarkingBuffer = buffer;
}, onError);
}
request.send();
}
Проблема, которую я обнаружил, заключается не в XMLHttpRequest
связанных материалах, а скорее в том, как справиться с decodeAudioData(data, callback)
, который выдает вам возвращаемые данные только через обратный вызов, и поэтому я хочу запустить действие i там, чтобы добавить это в мое хранилище Redux.
На данный момент моя saga выглядит так, но недостающий выход перед decodeAudio кажется проблемой:
import { takeLatest } from "redux-saga";
import { call, put } from "redux-saga/effects";
import axios from "axios";
import * as acts from "actions/playList";
const audioFileRequest = (url) => {
return axios.get(url, {
withCredentials: true,
responseType: "arraybuffer",
})
.then(({ data }) => data)
.catch(({ error }) => error);
};
const decodeAudio = (undecodedData, audioContext) => {
return audioContext.decodeAudioData(undecodedData, (buffer) => {
acts.recivedAudioFile(buffer); // no yeald ???
});
};
function *fetchAudio({ url, audioContext }) {
try {
let rawAudioData = yield call(audioFileRequest, url);
decodeAudio(rawAudioData, audioContext); // no yield ???
}
catch (error) {
yield put(acts.errorFetchingAudioFile(error));
}
}
export function *watchFetchAudio() {
yield takeLatest(acts.AUDIO_FILE_REQUEST, fetchAudio);
}
Ответ №1:
Я думаю, вы можете преобразовать функцию декодирования звука с помощью es6-promise и использовать метод вызова redux saga.
const decodeAudio = ({rawAudioData, audioContext}) => {
return new Promise((resolve, reject) => {
audioContext.decodeAudioData(rawAudioData, (buffer) => {
resolve({buffer}); // or reject if failed
});
}).then(({buffer}) => buffer).catch(error => error)
};
function *fetchAudio({ url, audioContext }) {
try {
let rawAudioData = yield call(audioFileRequest, url);
let buffer = yield call(decodeAudio, {rawAudioData, audioContext});
acts.recivedAudioFile(buffer);
}
catch (error) {
yield put(acts.errorFetchingAudioFile(error));
}
}
Комментарии:
1. При выходе после того, как я написал это и сам подумал об этом. Спасибо за быстрый ответ!
2. Приветствую .. 🙂 @CpILL