【问题标题】:how can I wait for 2 promises that check status of URLs to be completed before stating a new promise在陈述新的承诺之前,我如何等待 2 个检查 URL 状态的承诺完成
【发布时间】:2020-08-17 22:11:44
【问题描述】:

大家好

在设定承诺和玩弄结果时遇到问题。

我定义了 2 个 URL 数组,目标是通过仅保留存在的文件来过滤文件(使用 fetch),然后在完成后触发一个显示结果的函数。

我想使用 Promise 方法和 fetch() 函数。

我为每个数组创建了 1 个仅过滤现有文件的承诺。在触发另一个函数之前,我需要等待 2 个 Promise 完成。

我查看了互联网并尝试了多种方法,但无法使其按预期工作。它显示了结果,但我不能玩它们,所以我可能做错了。

很高兴得到一些帮助!

见下面我的代码:

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');
});

再次感谢 亚历克斯

【问题讨论】:

    标签: javascript promise async-await fetch


    【解决方案1】:

    这不能正常工作,因为您以错误的方式编写了 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))
    });
    

    编码愉快!

    【讨论】:

    • @Alex 太好了。如果它可以帮助您解决问题,请将其标记为答案。谢谢。
    【解决方案2】:

    您需要一个回调来将结果返回给您,同步函数不会返回您想要的任何结果。

    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)
    })
    

    【讨论】:

    • 我曾尝试在 1 个 promise 内使用您的 doFetch 函数,但没有成功。因为我喜欢你的函数,所以我想用它来使用 promise.all 并行检查主数组和辅助数组。然后,一旦两者都完成,并且只有完成后,我将显示结果。无法弄清楚如何处理它。我总是出错.....干杯亚历克斯
    【解决方案3】:

    你可以使用Promise.all()

    这样的东西应该可以工作

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

    Promise.all 将在所有作为参数提供的 Promise 解析后解析。

    如果您不关心捕获网络错误,也可以使用Promise.allSettled()

    【讨论】:

      猜你喜欢
      • 2019-05-29
      • 2016-10-16
      • 2020-04-22
      • 2017-06-17
      • 2017-07-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多