javascript - 在上下文 A 中准备上下文 B 的变量并在上下文 B 中解析它们

标签 javascript jquery ajax

目前,我正在尝试使重复的 Ajax 调用动态化,以便我的代码变得更易于管理。在这样做时,我遇到有时需要动态数据属性和值。始终只有一个数据值发生变化,其他参数保持不变。这样做我可以轻松地实现链式 promise 。

下面是我用作 Ajax 调用模板的示例:

var prepareAjax = {
    iterateValues: [1230,1280,4000,9000],
    ajaxOptions: [{
        timeout: 10000,
        type: "GET",
        data: `{
            param1: item,
            param2: obj.sessionId,
            param3: 1
        }`,     
        url: 'https://someurl.tld/target'
    }],
    sessionId: '<somestring>'
};

在这个对象之后,我调用一个函数,该函数应该从对象中提取ajaxOptions,如下所示:

function fetchChain(obj)=>{

    var ajaxPromises    = [], tempObj;

    obj.iterateValues.map((item, index)=> {

        tempObj         = obj.ajaxOptions[0];
        tempObj.data    = eval('('+tempObj.data+')');

        ajaxPromises.push(new Promise(
            (resolve, reject)=>{

                namespace.fetchData(tempObj);

            }
        );
    }
}

我在这里所做的是为每个 ìterateValue 创建一个 promise 和 Ajax 调用。然后我使用 eval(是的,邪恶)来解析当前上下文 (fetchChain) 的变量并将其提供给 fetchData。这些函数是在命名空间内执行的,因此我在示例中使用 namespace.fetchChain(prepareAjax) 来调用它们。

问题

此示例仅适用于一次迭代,因为即使我只评估/修改 tempObj,eval 似乎也会永久更改 obj,但显然我想重用每次迭代的模板。唯一需要解析的值是 item,参数保持不变。

我也知道 new Function()eval 更好的替代品,但我也无法让它工作。对我来说更奇怪的是,该函数以前在直接在 Ajax-Call 内部评估数据属性时起作用,而没有使用像 fetchChain() 那样的准备函数。即使在阅读了有关 SO 的几个答案之后,我仍被困在这一点上。

为了完整起见,这里是 fetchData 函数:

function fetchData(obj)=>{

    // single ajax-calls should use a delay of 0
    obj.timeout = ((obj.timeout) ? obj.timeout : 10000),
    obj.retries = ((obj.retries) ? obj.retries : 5),
    obj.delay   = ((obj.delay) ? obj.delay : 1000),
    obj.type    = ((obj.type) ? obj.type : "GET"),
    obj.cnt     = ((obj.cnt) ? obj.cnt++ : 0);

    var sumDelay = obj.delay*(obj.cnt+1);

    setTimeout(()=>{
        return new Promise((resolve, reject)=>{

            return $.ajax(obj)
            .done((response)=>{

                return resolve(response);

            }).fail((error)=>{
                if(obj.cnt++ >= obj.retries){   
                    return resolve('Error');
                }
                fun.fetchData(obj);
            }).always((xd)=>{
            })
        })
    }, sumDelay)
}

解决方案

我想到的一个解决方案是在将对象提供给 fetchChain() 之前准备好该对象。或者更清楚地说:在创建 prepareAjax 的上下文中。显然我更愿意直接在 fetchChain() 中处理这个过程。

错误

当如上所述执行 fetchChain 时,我在 eval 内的第二次迭代中收到错误 Unexpected Identifier 。 ([object Object]) 调试时,可以看到 obj 也更改了 data 的值。

最佳答案

为什么你不做一些类似动态获取该 obj 的事情呢?

例如:

const iterateValues = [1230,1280,4000,9000];
const getAjaxOpts = value => {
  return {
    ajaxOptions: [{
      timeout: 10000,
      type: "GET",
      data: /* apply data here from value */    
      url: 'https://someurl.tld/target'
    }],
  sessionId: '<somestring>'
  };
};

并进行如下迭代:

const mapped = iterateValues.map(x => getAjaxOpts(x));
// do your promise things afterwards

关于javascript - 在上下文 A 中准备上下文 B 的变量并在上下文 B 中解析它们,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53603811/

相关文章:

javascript - 如何使用回车键聚焦到下一个输入

Javascript:分割键值(带空格)

javascript - 嵌套 json 传入 ajax 调用

javascript - 使用 clamp.js 在 React 中进行线夹导致 IE11 中的对象错误

jquery -/statuses/user_timeline 仍然可以通过 JavaScript 读取吗?

javascript - 本地存储javascript变量到php

php - 创建一个动态的单页 Web 应用程序

javascript - AWS-Amplify,如何在 Angular 登录后重定向到另一个 URL?

javascript - 匿名函数中循环内的变量范围

javascript - Angular 应用程序中的 Firebase UI Auth 小部件