Как создать al oop, который можно программно повторять при выполнении внутреннего обратного вызова? - PullRequest
0 голосов
/ 05 августа 2020

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

assetsArr.forEach(asset => {
   myLoader.upload(asset, () => {
      // Go to next loop / iteration here
   })
});

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

Есть ли способ l oop over assetsArr, но только go к следующей итерации / l oop после выполнения этого обратного вызова?

Ответы [ 2 ]

1 голос
/ 05 августа 2020

Вы можете сделать это, заключив myLoader в Promise. Поскольку у меня нет кода для myLoader, я смоделирую его с задержкой, которая ждет всего несколько секунд.

async function dummyUpload(asset){
    return new Promise(resolve => {
         console.log("dummyUpload",asset);
         setTimeout(resolve,3000);
    });
}

async function test(assets){
    for(var i=0;i<assets.length;i++){
        var asset = assets[i];
        console.log("starting",asset);
        await dummyUpload(asset);
        console.log("finished",asset);
    };
}
var assets = [1,2,3];
test(assets);

Способ обертывания вашей функции загрузки довольно прост:

async function loaderFunction(asset){
    return new Promise( resolve => {
        myLoader.upload(asset, resolve);
    });
}

Вы также можете проверить, поддерживает ли ваш «загрузчик» Promise- основанный на интерфейсе, который был бы лучше, чем оборачивание другим Promise.

0 голосов
/ 05 августа 2020

Создайте функцию loader, как показано ниже, и вызовите ее с помощью loader(assetsArr, 0);. Внутри функции callback в конце добавьте код index++; и отметьте if (index < assetsArr.length), затем loader(assetsArr, index);.

Протестируйте его ниже. Для тестирования я добавил собственный код для myLoader.

let myLoader = {
  upload : (asset, callback) => setTimeout(callback, 1000)
};

let assetsArr = [1, 2, 3];

function loader(assetsArr, index) {
  let asset = assetsArr[index];
  myLoader.upload(asset, () => {
    console.log(index);
    // Go to next loop / iteration here      
    index++;
    if (index < assetsArr.length) {
      loader(assetsArr, index);
    }
  })
}

loader(assetsArr, 0);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...