使用生成器多次调用API并仅在所有请求完成后才能解决? [英] Using a generator to call an API multiple times and only resolve when all requests are finished?

查看:131
本文介绍了使用生成器多次调用API并仅在所有请求完成后才能解决?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作一个简单的NodeJS应用程序,并将其从回调地狱中重构出来.

I'm making a simple NodeJS app and I'm refactoring it out of my callback hell.

我已经意识到可以使用生成器,但是我一直在努力确切地了解如何使用它们.

I've realised generators could be used but I'm struggling to grasp exactly how to use them.

这是我的功能的基本流程(我正在使用request-promise模块):

Here's the basic flow of my function (I'm using the request-promise module):

  // Iterate through keys to get values for
  Object.keys(sourceData).forEach(function(key){
    makeRequest(key);
  })

makeRequest是一个基本上可以完成此功能的函数(不完整):

makeRequest is a function that basically does this (it's incomplete):

 // Make Request
 function makeRequest(key) {
   rp(apiEndpoint)
     .then((data) => {
        staticDictionary[key] = data.value;
   })
 }

我想同步调用端点,等到它完成获取数据后,再使用生成器继续循环中的下一个键.

I want to synchronously make a call to the endpoint, wait until it's finished getting the data, then move on to the next key in the loop using generators.

有人可以帮忙吗?

推荐答案

您可以使用.reduce()和promises依次对请求进行排序.

You can sequence your requests one after the other, using .reduce() and promises.

// Make Request
function makeRequest(key) {
   // use the key to construct the apiEndpoint here
   return rp(apiEndpoint).then((data) => {
        return data.value;
   });
}

Object.keys(sourceData).reduce(function(p, key){
    p = p.then(function(dictionary) {
        return makeRequest(key).then(function(data) {
            dictionary[key] = data;
            return dictionary;
        });
    }
}, Promise.resolve({})).then(function(dictionary) {
    // dictonary contains all your keys here
});

但是,由于您的请求都不依赖于先前的请求,因此您还可以并行运行它们:

But, since none of your requests depend upon the prior requests, you could also run them all in parallel:

// Make Request
function makeRequest(key) {
   // use the key to construct the apiEndpoint here
   return rp(apiEndpoint).then((data) => {
        return data.value;
   });
}

// Iterate through keys to get values for
 var staticDictionary = {};
 Promise.all(Object.keys(sourceData).map(function(key){
     return makeRequest(key).then(function(data) {
         staticDictionary[key] = data;
     });
 })).then(function() {
     // staticDictionary is fully available here
 });


使用Bluebird Promise库,您可以使用Promise.props(),它使用具有Promise的对象作为值,并返回具有相同键但将值解析为值的对象(您传入地图对象并返回地图对象):


Using the Bluebird promise library, you could use Promise.props() which takes an object with promises as values and returns an object with the same keys, but resolved values as values (you pass in a map object and get back a map object):

// Make Request
function makeRequest(key) {
   // use the key to construct the apiEndpoint here
   return rp(apiEndpoint).then((data) => {
        return data.value;
   });
}

var promiseMap = {};
Object.keys(sourceData).forEach(function(key) {
    promiseMap[key] = makeRequest(key);
})
return Promise.props(promiseMap).then(function(dictionary) {
    // dictionary is available here
});

这篇关于使用生成器多次调用API并仅在所有请求完成后才能解决?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆