【问题标题】:The best way to wait for the completion async function before returning data在返回数据之前等待完成异步函数的最佳方法
【发布时间】:2017-08-04 15:14:57
【问题描述】:

在返回数据之前等待所有并行异步函数完成的最佳方法是什么?

请求异步工作,下面的函数将返回一个空数组。

import request from 'request'

// List of urls
const urls = [
  'http://someurl.com/1.json',
  'http://someurl.com/2.json',
  'http://someurl.com/3.json',
]

function getData () {
  // An array that will contain data
  let result = []
  
  // Request data from all urls
  urls.forEach(i => {
    // Function works asynchronously
    request(i, (err, res, body) => {
      if(err) throw err
      
      const data = JSON.parse(body)
      
      result.push(i.someValue)
    })
  })

  return result // Returns an empty array :(
}

【问题讨论】:

  • Promise.all()
  • 你用的是什么请求库?import request from 'require'没有任何意义
  • @Aron https://www.npmjs.com/package/request
  • @Aron 我的错。对不起。发布固定
  • 首先,您不能等待异步响应完成后再返回。有关该问题的所有详细信息,请参阅How do I return the response from an asynchronous call?

标签: javascript arrays asynchronous request promise


【解决方案1】:

如果您可以使用 Promise,那么最好的方法就是使用它们。 确保你的请求函数返回一个承诺,这样你就可以像这样:

var request = function request( url ) {
    return new Promise(function requestPromise( resolve, reject ) {
        myAjaxCallOrOtherAsyncCall( url, function( error, response ) {
            if (error) reject(error);
            else resolve(response);
        })
    });
};

var getData = function getData( urls ) {
    return Promise.all( urls.map(request) );
};

var urls = [
  'http://someurl.com/1.json',
  'http://someurl.com/2.json',
  'http://someurl.com/3.json',
];

getData(urls).then(function( responses ) {
    var results = responses.map(JSON.parse);
    // do somethign with async results
});

【讨论】:

    【解决方案2】:

    使用Promise.all() 等待所有承诺完成,但这确实需要您使用返回承诺的请求库,例如axios

    import axios from 'axios'
    
    // List of urls
    const urls = [
        'http://someurl.com/1.json',
        'http://someurl.com/2.json',
        'http://someurl.com/3.json',
    ]
    
    function getData() {
        return new Promise((resolve, reject) => {
    
            const promises = urls.map(url => axios.get(url)); // array of pending promises
    
            Promise.all(promises) // creates single promise that resolves when all `promises` resolve
                .then(responses => {
                    const dataArray = responses.map(response => response.data);
                    return resolve(dataArray);
                }) // resolves with an array of response data
                .catch(reject);
        })
    }
    
    getData()
        .then(data => {
            // do something
        })
    

    【讨论】:

      【解决方案3】:

      尝试使用触发器。收集完所有数据后使用

      $(trigger_obj).trigger('loading_complete');
      

      然后让它成为一个处理程序

      $(trigger_obj).on('loading_complete', function () {
        \\ logic ...
      });
      

      【讨论】:

      • 这与多个异步调用有什么关系?
      【解决方案4】:

      使用https://github.com/request/request-promise-native,您可以方便Promise.all,正如其他人已经指出的那样:

      import Request from 'request-promise-native'
      
      // List of urls
      const urls = [
        'http://someurl.com/1.json',
        'http://someurl.com/2.json',
        'http://someurl.com/3.json',
      ]
      
      // The simplest form to create a bunch of request promises:
      Promise.all(urls.map(Request))
      
      // Otherwise it could look as follows:
      const urlPromises = urls.map(url => Request({
        uri: 'http://www.google.com'
        // and more options
      }))
      
      // Or with promise chains:
      const urlPromiseChain = (url) => {
        return Request(url)
               .then(doSomethingWithResponse)
               .catch(logButDontFailOnError)
      }
      
      const urlPromiseChains = urls.map(urlPromiseChain)
      
      Promise.all(urlPromises /* or urlPromiseChains */)
      .then(responses => console.log(responses))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-17
        • 1970-01-01
        • 2016-09-23
        • 1970-01-01
        相关资源
        最近更新 更多