javascript - 链式获取 Promise(JSON、React、Webpack、NodeJS)

标签 javascript node.js reactjs fetch

我需要获取某些内容 10 次并返回每个请求的 JSON 并将其推送到状态。 大多数抓取工作都可以进行,但速度会减慢一半,并在完成之前停止。 这些 promise 似乎接受“cors”响应,而不是实际的 json,因此会过早触发。

另外,我不喜欢我必须多次重复相同的代码才能更改偏移量,但是我花了几个小时摆弄 for 循环,然后我陷入困境,所以如果你们能提出更好的方法能做到这一点那就太棒了。

代码如下:

function FetchAll(API_KEY, CX, query, E, that, pushState){

    fetch(`https://www.googleapis.com/youtube/v3/channels?part=contentDetails&id=${E.target.value}&key=${API_KEY}`, {
      method: 'get',
      headers : { 
        'Content-Type': 'application/json',
        'Accept': 'application/json'
       }
    }).then(function(response){
      return response.json()
    }).then(function(uploads){
        console.log(uploads)
      return fetch(`https://www.googleapis.com/youtube/v3/playlistItems?playlistId=${uploads.items[0].contentDetails.relatedPlaylists.uploads}&key=${API_KEY}&part=snippet&maxResults=50`)
    }).then(response => {
      return response.json()
    }).then(function(data){
        console.log(data)
      that.setState({yt:data})
    }).then(function(){
      return fetch(`https://www.googleapis.com/customsearch/v1?key=${API_KEY}&num=10&cx=${CX}&q=${query}&start=${1}`)
    }).then(function(response){
      return response.json();
    }).then(r => pushState(r))
    .then(function(){
      return fetch(`https://www.googleapis.com/customsearch/v1?key=${API_KEY}&num=10&cx=${CX}&q=${query}&start=${11}`)
    }).then(function(response){
      return response.json();
    }).then(r => pushState(r))
    .then(function(){
      return fetch(`https://www.googleapis.com/customsearch/v1?key=${API_KEY}&num=10&cx=${CX}&q=${query}&start=${21}`)
    }).then(function(response){
      return response.json();
    }).then(r => pushState(r))
    .then(function(){
      return fetch(`https://www.googleapis.com/customsearch/v1?key=${API_KEY}&num=10&cx=${CX}&q=${query}&start=${31}`)
    }).then(function(response){
      return response.json();
    }).then(r => pushState(r))
    .then(function(){
      return fetch(`https://www.googleapis.com/customsearch/v1?key=${API_KEY}&num=10&cx=${CX}&q=${query}&start=${41}`)
    }).then(function(response){
      return response.json();
    }).then(r => pushState(r))
    .then(function(){
      return fetch(`https://www.googleapis.com/customsearch/v1?key=${API_KEY}&num=10&cx=${CX}&q=${query}&start=${51}`)
    }).then(function(response){
      return response.json();
    }).then(r => pushState(r))
    .then(function(){
      return fetch(`https://www.googleapis.com/customsearch/v1?key=${API_KEY}&num=10&cx=${CX}&q=${query}&start=${61}`)
    }).then(function(response){
      return response.json();
    }).then(r => pushState(r))
    .then(function(){
      return fetch(`https://www.googleapis.com/customsearch/v1?key=${API_KEY}&num=10&cx=${CX}&q=${query}&start=${71}`)
    }).then(function(response){
      return response.json();
    }).then(r => pushState(r))
    .then(function(){
      return fetch(`https://www.googleapis.com/customsearch/v1?key=${API_KEY}&num=10&cx=${CX}&q=${query}&start=${81}`)
    }).then(function(response){
      return response.json();
    }).then(r => pushState(r))
    .then(function(){
      return fetch(`https://www.googleapis.com/customsearch/v1?key=${API_KEY}&num=10&cx=${CX}&q=${query}&start=${91}`)
    }).then(function(response){
      return response.json();
    }).then(r => pushState(r))
    .then(function(){
      return fetch(`https://www.googleapis.com/customsearch/v1?key=${API_KEY}&num=10&cx=${CX}&q=${query}&start=${101}`)
    }).then(function(response){
      return response.json();
    }).then(r => pushState(r))

}

export default FetchAll

如果您感到困惑,FetchAll 正在主 App.js 文件中被调用,所有内容都以参数形式发送给它。

这是pushState(如果需要)

FetchAll(API_KEY, CX, query, e, that,
    (r) => {
      console.log(r)
      let c = that.state.compareRaw
      c.push(r)
      that.setState({
        compareRaw: c
      })
    }
    )
}

'that' is a reference to 'this'

非常感谢任何帮助或提示。谢谢!

最佳答案

首先判断哪些请求是 waterfall 请求,哪些请求是并行请求。

在 waterfall 模型中,当前请求依赖于先前的请求结果,并通过排序 .then() 函数进行处理

并行模型请求是独立的,并且可以同时触发。这个问题可以通过 bluebird 作为 Promise 的一个很好的辅助工具来解决。

const Promise = require('bluebird');
Promise.all([fetch(...), fetch(...)...., fetchN(...)], 
            (result1, result2, result3 ..., resultN) => {
              //handle results
            })

您始终可以将 api 调用包装在函数中:

function search(start, limit) {
    return fetch(`https://www.googleapis.com/customsearch/v1?key=${API_KEY}&num=${limit}&cx=${CX}&q=${query}&start=${start}`)  
}

现在大家在一起

fetch(...) // request 1
.then((response) => fetch(...)) // request 2
.then((response) => {
   const apiCalls = [];
   for let i = 0; i < 10; i++ {
      apiCalls.push( search(i*10+1, 10) );
   }
   return Promise.all(apiCalls);
})
.then((...results) => {
   // handle search results
})

希望有帮助。

关于javascript - 链式获取 Promise(JSON、React、Webpack、NodeJS),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42695117/

相关文章:

node.js - Knex with Postgres 以意想不到的方式存储时间戳

node.js - socket.io 确保客户端重新连接时的状态

javascript - 使用 React Route 部署到 S3 后看到空白页面

javascript - 使用 Array.reduce() 将数组转换为对象

macos - Nodejs www mac os x 服务器

javascript - 如何使用 TypeScript 在 React Native 中使用 forwardRef 和 FunctionComponent

reactjs - 属性 'location' 在类型 'Readonly<{}> 上不存在 - React Router 和 Typescript

javascript - CRONTAB 执行 Python,使用 puppeteer 执行 Node 来进行网页抓取不起作用

javascript - 设备方向元数据

javascript - 使用Javascript编写纯文本?