как я могу ждать 2 обещания, которые проверяют состояние URL-адресов, чтобы завершить, прежде чем заявить новое обещание - PullRequest
0 голосов
/ 03 мая 2020

Хо всем

Есть проблемы с настройкой обещаний и игрой с результатами.

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

Я бы хотел использовать методологию обещаний и функцию fetch ().

Я создал 1 обещание на массив, который фильтрует только существующие файлы. Мне нужно подождать, пока 2 обещания будут выполнены, прежде чем запускать другую функцию.

Я посмотрел на inte rnet и попробовал несколько способов, но не могу заставить его работать так, как я ожидаю. он показывает результаты, но я не могу играть с ними, поэтому, возможно, я сделал это неправильно.

Рад получить помощь!

См. ниже мой код:

const Primary = [
    'https://jsonplaceholder.typicode.com/posts',       //file exists
    '/data/file01',                                     //file dont exist
    'https://jsonplaceholder.typicode.com/users',       //file exists
    '/data/file02'                                      //file dont exist
];

const Diverse = [
    '/data/file0.txt',                                  //file dont exist
    'https://jsonplaceholder.typicode.com/albums',      //file exists
    '/data/file5.txt'                                   //file dont exist
];

const P1 = new Promise(function(resolve, reject) {
    Primary.forEach(function (elem, index) {
        fetch( elem )
        .then(function(response) {
            if (response.status != 404) {
                arr1.push (response.url);
                return (response.url);
            }
        })
        .catch(function(error) {
            console.log("Error ", error);
        });
        if (index==(Primary.length-1))
            resolve (arr1);
    });
});

const P2 = new Promise(function(resolve, reject) {
    Diverse.forEach(function (elem, index) {
        fetch( elem )
        .then(function(response) {
            if (response.status != 404) {
                arr2.push (response.url);
                return (response.url);
                }
        })
        .catch(function(error) {
            console.log("Error ", error);
        });
        if (index==(Diverse.length-1))
            resolve (arr2);
    });
});

// Promise.all waits until all jobs are resolved
Promise.all( [P1, P2] )
.then(function (responses) {
    console.log ('Responses:', responses);
    responses.forEach(function (element, index) {
        console.log (element);
        element.forEach(function (el, id) {
            console.log (el);
        });
    });

    console.log('Test sync');
});

Еще раз спасибо, Алекс

Ответы [ 3 ]

1 голос
/ 03 мая 2020

Это не работает должным образом, поскольку вы неправильно написали функции P1, P2.

Diverse.forEach(function (elem, index) {
...
  if (index==(Primary.length-1))
    resolve(arr);
}

^ Это действительно плохая практика, поскольку JS является синхронным и не возвращает желаемый результат. Пожалуйста, перепишите такие функции, как это -

const P2 = new Promise((resolve, reject) => {
    let fetchPromises = Diverse.map((elem, index) => fetch(elem));
    Promise.all(fetchPromises)
        then(responses => resolve(responses))
});

Удачного кодирования!

1 голос
/ 03 мая 2020

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

const Primary = [
    'https://jsonplaceholder.typicode.com/posts',       //file exists
    '/data/file01',                                     //file dont exist
    'https://jsonplaceholder.typicode.com/users',       //file exists
    '/data/file02'                                      //file dont exist
];

const Diverse = [
    '/data/file0.txt',                                  //file dont exist
    'https://jsonplaceholder.typicode.com/albums',      //file exists
    '/data/file5.txt'                                   //file dont exist
];

const doFetch = (url) => fetch(url).then(response=>{
    let promise = new Promise((resolve,reject) =>{
        if(response.status == 200){
            resolve(response.json())
        }else{
            reject(response.status)
        }
    })

    return promise
})

let callback = {
    success: (data) => {
        console.log(data)
    },
    error:(err)=>{
        console.log(err)
    }
}

Primary.map( (url) => {
    doFetch(url)
    .then(callback.success, callback.error)
})

Diverse.map( (url) => {
    doFetch(url)
    .then(callback.success, callback.error)
})
0 голосов
/ 03 мая 2020

Вы можете использовать Promise.all ()

Что-то вроде этого должно работать

Promise.add(Primary.map(fetch)).then((allResponsens) => ...);

Promise.all разрешится, как только все обещания, представленные как разрешение аргумента.

Вы также можете использовать Promise.allSettled () , если вас не волнует обнаружение сетевых ошибок

...