如何处理对后端服务进行相同调用的多个浏览器脚本

2023-05-16前端开发问题
6

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

问题描述

限时送ChatGPT账号..

我有一个网页,其中的不同部分都需要相同的后端数据.每个都是孤立的,因此它们最终都会对后端进行相同的调用.

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.

转储联系人列表:

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];
    }
  });
};

下面是一些使用这三个函数的示例代码:

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);
});

上述例程使用全局 log() 函数.可以使用 console.log() 代替.上面的 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>

当上面的代码运行时,你会看到:

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=preview

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;
}

这有一个警告,即对于 null 的实际结果会失败,否则它可以很好地完成工作.

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

您现在可以缓存任何 promise 返回函数 - 上面的版本只缓存忽略参数 - 但您可以构造一个类似的函数,它具有 Map 并基于不同的参数进行缓存 - 但让我们专注于您的用例.

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

cache 方法实际上甚至与 Promise 无关——它所做的只是获取一个函数并缓存它的结果——你可以将它用于任何事情.事实上,如果你正在使用像 underscore 这样的库,你可以使用 _.memoize 来为你做这件事.

The cache method is actually not even related to promises - all it does is take a function and cache its result - you can use it for anything. In fact if you're using a library like underscore you can use _.memoize to do it for you already.

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

The End

相关推荐

js删除数组中指定元素的5种方法
在JavaScript中,我们有多种方法可以删除数组中的指定元素。以下给出了5种常见的方法并提供了相应的代码示例: 1.使用splice()方法: let array = [0, 1, 2, 3, 4, 5];let index = array.indexOf(2);if (index -1) { array.splice(index, 1);}// array = [0,...
2024-11-22 前端开发问题
182

JavaScript小数运算出现多位的解决办法
在开发JS过程中,会经常遇到两个小数相运算的情况,但是运算结果却与预期不同,调试一下发现计算结果竟然有那么长一串尾巴。如下图所示: 产生原因: JavaScript对小数运算会先转成二进制,运算完毕再转回十进制,过程中会有丢失,不过不是所有的小数间运算会...
2024-10-18 前端开发问题
301

JavaScript(js)文件字符串中丢失"\"斜线的解决方法
问题描述: 在javascript中引用js代码,然后导致反斜杠丢失,发现字符串中的所有\信息丢失。比如在js中引用input type=text onkeyup=value=value.replace(/[^\d]/g,) ,结果导致正则表达式中的\丢失。 问题原因: 该字符串含有\,javascript对字符串进行了转...
2024-10-17 前端开发问题
437

layui中table列表 增加属性 edit="date",不生效怎么办?
如果你想在 layui 的 table 列表中增加 edit=date 属性但不生效,可能是以下问题导致的: 1. 缺少日期组件的初始化 如果想在表格中使用日期组件,需要在页面中引入 layui 的日期组件,并初始化: script type="text/javascript" src="/layui/layui.js"/scrip...
2024-06-11 前端开发问题
455

Rails/Javascript:如何将 rails 变量注入(非常)简单的 javascript
Rails/Javascript: How to inject rails variables into (very) simple javascript(Rails/Javascript:如何将 rails 变量注入(非常)简单的 javascript)...
2024-04-20 前端开发问题
5

CoffeeScript 总是以匿名函数返回
CoffeeScript always returns in anonymous function(CoffeeScript 总是以匿名函数返回)...
2024-04-20 前端开发问题
13