我该如何处理多个浏览器脚本制作到后端服务相同的调用 [英] How do I handle multiple browser scripts making the same calls to the back-end service

查看:199
本文介绍了我该如何处理多个浏览器脚本制作到后端服务相同的调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个网页,它的所有不同部分需要同样的后端数据。每个分离,所以它们每个最终最终使得向后端​​相同的呼叫。

I have a web page where different parts of it all need the same back-end data. Each is isolated, so they each end up eventually making the same calls to the back-end.

什么是避免到Web服务器的调用,当一个已在进行中,由同一网页?

What is the best way to avoid making a call to the web server when one is already in progress and initiated by a different piece of code on the same web page?

下面是一个例子。我将使用的setTimeout来模拟一个异步调用。

Here's an example. I'll use setTimeout to simulate an asynchronous call.

让我们假设有一个返回的联系人列表,这基本上是字符串在本实施例的简单阵列的异步函数:

Let's assume there's an async function that returns the list of contacts, which is basically a simple array of strings in this example:

var getContacts = function() {
  log('Calling back-end to get contact list.');
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      log('New data received from back-end.');
      resolve(["Mary","Frank","Klaus"]);
    }, 3000);
  });
};

现在,让我们来创建三个不同的功能,每个调用上面的函数用于不同的目的。

Now, let's create three separate functions that each call the above function for different purposes.

dump出来的联系人列表:

Dump out the list of contacts:

var dumpContacts = function() {
  getContacts().then(function(contacts) {
    for( var i = 0; i < contacts.length; i++ ) {
      log( "Contact " + (i + 1) + ": " + contacts[i] );
    }
  });
};

确定一个特定的接触是在列表中:

Determine if a particular contact is in the list:

var contactExists = function(contactName) {
  return getContacts().then(function(contacts) {
    return contacts.indexOf(contactName) >= 0 ? true : false;
  });
};

获取第一个联系人的名称:

Get the name of the first contact:

var getFirstContact = function() {
  return getContacts().then(function(contacts) {
    if ( contacts.length > 0 ) {
      return contacts[0];
    }
  });
};

和这里有一些例子code使用这三个功能:

And here is some example code to use these three functions:

// Show all contacts
dumpContacts();

// Does contact 'Jane' exist?
contactExists("Jane").then(function(exists){
  log("Contact 'Jane' exist: " + exists);
});

getFirstContact().then(function(firstContact){
  log("first contact: " + firstContact);
});

以上程序使用一个全局日志()函数。的console.log()可以被代替使用。上述日志()函数日志的浏览器窗口,并实现如下:

The above routines make use of a global log() function. console.log() could be used instead. The above log() function log's to the browser window and is implemented as follows:

function log() {
  var args = Array.prototype.slice.call(arguments).join(", ");
  console.log(args);
  var output = document.getElementById('output');
  output.innerHTML += args + "<br/>";
}

和需要在HTML以下内容:

and requires the following in the html:

<div id='output'><br/></div>

在运行上述code,您将看到:

When the above code is run, you will see:

Calling back-end to get contact list.

New data received from back-end.

三次,这是不必要的。

这怎么能解决吗?

这样品是在Plunker可以执行:
http://plnkr.co/edit/6ysbNTf1lSf5b7L3sJxQ?p=$p$pview

This sample is on Plunker can be executed: http://plnkr.co/edit/6ysbNTf1lSf5b7L3sJxQ?p=preview

推荐答案

只是缓存结果的函数进行调用:

Just cache the result in the function making the call:

function cache(promiseReturningFn){
    var cachedVal = null;  // start without cached value
    function cached(){
        if(cachedVal) return cachedVal; // prefer cached result
        cachedVal = promiseReturningFn.apply(this, arguments); // delegate
        return cachedVal; // after we saved it, return it
    }
    cached.flush = function(){ cachedVal = undefined; };
    return cached;
}

这有失败对于那些空但除此之外,它得到很好的完成工作实际结果的警告。

This has the caveat of failing for actual results that are null but otherwise it gets the job done nicely.

您现在可以缓存任何承诺返回函数 - 只以上的版本缓存忽略的参数 - 但你可以构造一个类似,有一个地图和缓存根据不同的参数太多 - 但让我们专注于您的使用情况

You can now cache any promise returning function - the version above only caches ignoring arguments - but you can construct a similar one that has a Map and caches based on different arguments too - but let's focus on your use case.

var getContactsCached = cache(getContacts);

getContactsCached();
getContactsCached();
getContactsCached(); // only one async call ever made

缓存方法是居然连不相关的承诺 - 它是所有需要的功能,并缓存它的结果 - 你可以用它来做什么。事实上,如果您使用的是像库下划线你可以使用 _。memoize的来为你做了。

这篇关于我该如何处理多个浏览器脚本制作到后端服务相同的调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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