【问题标题】:Can I wait all the promise until it resolve? [duplicate]我可以等待所有的承诺直到它解决吗? [复制]
【发布时间】:2020-07-13 01:11:42
【问题描述】:

我有一个 nodejs 应用程序,它从不同的 api 获取数据,我想聚合来自不同 api 的数据,然后将其发送出去。但是我只能解决 api 数据获取的承诺,但 res.send 只发送空数组。我猜 res.send 没有等待 json() 函数解析并且已经发送了数据。我该如何解决这个问题?

app.get('/:keyword',(req,res)=>{
    let unsplashPromise = unsplash.search.photos(......)
    let pixabayPromise = fetch(......)
    let jsonPromise
    let data = []

    Promise.all([unsplashPromise, pixabayPromise]).then(files=>{
        files.map((promise)=>{
            if(promise.url.includes("unsplash")){
                promise.json().then((photos)=>{
                    photos.results.map((photo)=>{
                        data.push({
                            image_ID: photo.id,
                            thumbnails: photo.urls.thumb,
                            preview: photo.urls.regular,
                            title: photo.alt_description,
                            source: "unsplash",
                            tags: photo.tags
                        })
                    })
                })

            }else if(promise.url.includes("pixabay")){
                promise.json().then((json)=>{
                    json.hits.map((photo)=>{
                        data.push({
                            image_ID: photo.id,
                            thumbnails: photo.previewURL,
                            preview: photo.largeImageURL,
                            title: null,
                            source: "pixabay",
                            tags: photo.tags
                        })
                    })
                })
            }
            return data
        })
    }).then(()=>{
        res.send(data)
    })


})

【问题讨论】:

  • Promise.all(/* your promises */).then(/* your handling of those*/).then(data => res.send(data))
  • 你已经完成了Promise.all(...).then(...) 一次。您需要为每组承诺这样做。
  • @VLAZ 我尝试了你的 double then 方法,但没有成功
  • @miketsui3a 你return data了吗?
  • @VLAZ 你的意思是 ```Promise.all([x,y]).then(files=>{......return data}) 吗?

标签: javascript node.js express asynchronous promise


【解决方案1】:

试试这个,它会等待嵌套的 Promise。

app.get('/:keyword',(req,res)=>{
    let unsplashPromise = unsplash.search.photos(somthineg)
    let pixabayPromise = fetch(`somthing`)

    let data = []

    Promise.all([unsplashPromise, pixabayPromise]).then(files=>
        Promise.all(files.map((promise)=>{
            if(promise.url.includes("unsplash")){
                return promise.json().then((photos)=>{
                    photos.results.map((photo)=>{
                        data.push({
                            image_ID: photo.id,
                            thumbnails: photo.urls.thumb,
                            preview: photo.urls.regular,
                            title: photo.alt_description,
                            source: "unsplash",
                            tags: photo.tags
                        })
                    })
                })

            }
            if(promise.url.includes("pixabay")){
                return promise.json().then((json)=>{
                    json.hits.map((photo)=>{
                        data.push({
                            image_ID: photo.id,
                            thumbnails: photo.previewURL,
                            preview: photo.largeImageURL,
                            title: null,
                            source: "pixabay",
                            tags: photo.tags
                        })
                    })
                })
            }
            return Promise.resolve();
        }))
    ).then(() => {
        res.send(data);
    }).catch(err=>{
        console.log(err)
    })
})

【讨论】:

  • 试过但没用
  • 在第一个then 那里你有promise.json().then,你也需要等待他们。最简单的方法是将async 添加到您的函数中,然后添加await promise.json().then。在这种情况下,一旦收集到数据,就会执行 .thensend
  • 我已经更新了答案中的代码。
  • 这是一种从不同的承诺中逐个捕获错误的方法吗?假设我的第一个 api 提取失败,但仍然可以获取第二个 api 提取的数据
  • 您可以在.then 之前添加.catch 并设置一个标志是否要跳过请求。当您想检查Promise.all 中的每个承诺时,只需将.catch() 添加到每个人并将结果映射到一个空数组。那么你就没有错误了,失败的承诺将返回一个空数组。
【解决方案2】:

您可以添加 2 个标志,一个用于unsplash,另一个用于pixabay,一旦两者都为真,您就可以发送响应。例如

app.get('/:keyword',(req,res)=>{
let unsplashPromise = unsplash.search.photos(somthineg)
let pixabayPromise = fetch(`somthing`)
let unsplashPromiseDone, pixabayPromiseDone = false;

let data = []

Promise.all([unsplashPromise, pixabayPromise]).then(files=>{
    files.map((promise)=>{
        if(promise.url.includes("unsplash")){
            promise.json().then((photos)=>{
                photos.results.map((photo)=>{
                    data.push({
                        image_ID: photo.id,
                        thumbnails: photo.urls.thumb,
                        preview: photo.urls.regular,
                        title: photo.alt_description,
                        source: "unsplash",
                        tags: photo.tags
                    })
                })
                unsplashPromiseDone = true;
            })

        }else if(promise.url.includes("pixabay")){
            promise.json().then((json)=>{
                json.hits.map((photo)=>{
                    data.push({
                        image_ID: photo.id,
                        thumbnails: photo.previewURL,
                        preview: photo.largeImageURL,
                        title: null,
                        source: "pixabay",
                        tags: photo.tags
                    })
                })
            pixabayPromiseDone = true;
            })
        }
        if (unsplashPromiseDone && pixabayPromiseDone) {
            res.send(data)
        }
    })
}).catch(err=>{
    console.log(err)
})

})

【讨论】:

  • files.map 循环可以在内部承诺解析和标志设置之前完成。
猜你喜欢
  • 2014-03-12
  • 1970-01-01
  • 2022-01-17
  • 2017-05-25
  • 1970-01-01
  • 2021-02-02
  • 2021-08-17
  • 2019-04-29
相关资源
最近更新 更多