Пройти по массиву с запросами на сервер

Необходимо синхронизировать оффлайновые операции приложения на React native с сервером, для этого в приложении есть массив объектов. Для упрощения он будет выглядеть так

    myList = [{"isOnline:1"}, {"isOnline:0"}, {"isOnline:0"}, {"isOnline:1"}];

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

async syncOfflineOperations() {
....
  let promise = new Promise((resolve, reject) => {
            this.StorageListAllOperation.forEach(function(item) {
            if (item.isOnline == 0){
                fetch("url",{
                timeout: MyConstants.TIMEOUT,
                method: 'post',
                headers: {
                    Accept: 'application/json',
                    'Content-Type': 'application/json',
                },
                body: myBody
                }).then((response) => response.json())
                .then((json) => {
                    if (json.status == ok) {
                        // go other operations
                    }
                    else {
                        // stop foreach and return error code
                    }
                })
                .catch((error) => {
                    // stop foreach and return error code;
                });
    }
  }
}

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


Ответы (1 шт):

Автор решения: nörbörnën

Вот примерно так:

const MyConstants = {
    TIMEOUT: 10000
};

class Component {
    constructor() {
        this.StorageListAllOperation = [{ isOnline: 1 }, { isOnline: 0 }, { isOnline: 0 }, { isOnline: 1 }];
    }
    async syncOfflineOperations() {
        if (!this.StorageListAllOperation || this.StorageListAllOperation.length === 0) {
            return;
        }
        const fetchUrl = '';
        const fetchOptions = {
            timeout: MyConstants.TIMEOUT,
            method: 'post',
            headers: {
                'Accept': 'application/json', 'Content-Type': 'application/json',
            }
        };
        for (const item of this.StorageListAllOperation) {
            if (item.isOnline === 0) {
                try {
                    const resp = await fetch(fetchUrl, { ...fetchOptions, body: item });
                    const res = await resp.json();
                    console.log('res= ', res);
                    if (res.status === 'ok') {
                        // success handler
                        console.log('success status handler');
                    } else {
                        // fail status handler (eg: break)
                        console.log('fail status handler');
                    }
                } catch (err) {
                    // other errors handler (network error / syntax error)
                    console.error(err);
                }
            }
        }
    }
}

function fetch() {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve({
                json: () => Promise.resolve({ status: Math.random() > 0.5 ? 'ok' : 'fail' })
            });
        }, 100 * Math.random());
    });
}

new Component().syncOfflineOperations().then(console.log).catch(console.error);

MyConstants, Component, fetch - фейковые, сделаны для адекватного запуска примера.

→ Ссылка