Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何向JavaScript函数提供XMLHttpRequest承诺_Javascript_Jquery_Promise_Xmlhttprequest - Fatal编程技术网

如何向JavaScript函数提供XMLHttpRequest承诺

如何向JavaScript函数提供XMLHttpRequest承诺,javascript,jquery,promise,xmlhttprequest,Javascript,Jquery,Promise,Xmlhttprequest,在一个自动完成插件上乱搞,可以使用以下功能: $('#id').autocomplete({ source: {'test1':1, 'test2':2, 'test1':3} }); 与本地JSON不同,我需要生成一个XMLHttpRequest,并考虑了如下内容,虽然我没有得到错误,但我也没有得到任何结果: $('#id').autocomplete({ source: function() { var xhttp = new XMLHttpRequest(

在一个自动完成插件上乱搞,可以使用以下功能:

$('#id').autocomplete({
    source: {'test1':1, 'test2':2, 'test1':3}
});
与本地JSON不同,我需要生成一个XMLHttpRequest,并考虑了如下内容,虽然我没有得到错误,但我也没有得到任何结果:

$('#id').autocomplete({
    source: function() {
        var xhttp = new XMLHttpRequest();
        xhttp.onreadystatechange = function() {
            if (this.readyState == 4 && this.status == 200) {
                return JSON.parse(this.responseText);
            }
        };
        xhttp.open(method, url, true);
        xhttp.send();
    }
});
该插件的作者不久前发表了以下言论:

我没有计划直接调用库中的任何url。你呢 can-do是在ajax调用后将autocomplete设置为文本字段 返回,可以使用jQuery执行,如下所示:

$.ajax('myurl')。然后((数据)=>$('#myTextfield')。自动完成({ 资料来源:数据})

您不必担心将autocomplete设置为字段倍数 很多时候,当你需要改变方向时,它应该是这样工作的 来源

尝试过之后,正如预期的那样,
$.ajax()
在页面加载时启动了XMLHttpRequest请求,而在用户在搜索输入中输入字符时,这并不是预期的

我如何能够进行XMLHttpRequest以将数据源化到插件中?我假设我应该使用一个承诺,但是,如果不是,仍然会感谢任何帮助


谢谢

好吧,这就是插件的工作原理。它的肉和土豆是
createItems
函数,在keyup事件中调用,并负责用项目填充下拉列表。这里是它的关键部分():

函数createItems(字段:JQuery,选项:自动完成选项){
const lookup=field.val()作为字符串;
// ...
让计数=0;
常量键=Object.keys(opts.source);
for(设i=0;i=0){
append(createItem(查找、项、选项));
如果(opts.maximumItems>0&&++count>=opts.maximumItems){
打破
}
}
}
//跳过剩下的
}
如您所见,每次调用
createItems
时,它都会通过
source
object,将包含查找字符串的所有项变灰

因此,所有的数据部分都应该在那里,并且可以同步处理。这就是插件的方式,所有好的和坏的都来自这个方法

该插件的作者在此提出的最好的建议(不违背插件的功能)是在调用autocomplete之前使用AJAX预填充数据。事实上,这就是他在评论中所做的


现在,我们能做些什么?有人可能认为只要将
createItems
转换为异步函数就足够了——例如,如果它是一个函数,则调用
source
,并期望其结果是一个承诺。排除过程中的查找循环似乎非常简单,只需将AJAX调用的结果重新填充
源代码

但不幸的是,这并不是那么简单:有几个注意事项需要注意。例如,如果用户停止键入(触发第一个AJAX调用),然后再键入一些,然后再次停止(触发另一个AJAX调用),那么会发生什么情况?但是第一个调用实际上会在稍后到达?遗憾的是,我一直在使用的许多自动完成实现都遇到了相应的错误——如果只使用快速网络连接(更不用说仅在本地主机上)进行测试,那么复制该错误就不那么容易了


这似乎只是作者决定不扩展插件的原因之一。毕竟,它是为了解决一个特定的任务而构建的——而且它做得很好。因此,除非你想把它用叉子叉出来,并从本质上把它改写成“两个策略”之一,否则我建议你考虑换个地方。

谢谢你,raina77ow,他一直在下兔子洞,并怀疑可能不会有另一个开口。很高兴我现在知道了!您好,我再次查看了您发布的代码,并认为“Javascript何时支持接口?”,但没有找到任何内容。然后不幸地发现我被愚弄了。再次感谢你的回答。
function createItems(field: JQuery < HTMLElement > , opts: AutocompleteOptions) {
  const lookup = field.val() as string;

  // ...
  
  let count = 0;
  const keys = Object.keys(opts.source);
  for (let i = 0; i < keys.length; i++) {
    const key = keys[i];
    const object = opts.source[key];
    const item = {
      label: opts.label ? object[opts.label] : key,
      value: opts.value ? object[opts.value] : object,
    };
    if (item.label.toLowerCase().indexOf(lookup.toLowerCase()) >= 0) {
      items.append(createItem(lookup, item, opts));
      if (opts.maximumItems > 0 && ++count >= opts.maximumItems) {
        break;
      }
    }
  }

  // skipped the rest
}