Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/435.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 非阻塞同步AJAX_Javascript_Ajax - Fatal编程技术网

Javascript 非阻塞同步AJAX

Javascript 非阻塞同步AJAX,javascript,ajax,Javascript,Ajax,有没有一种方法可以执行不冻结浏览器的同步AJAX查询?在我看来,在大多数情况下,使用同步请求要容易得多,但它们阻止代码的其他部分执行的事实是一个真正的杀手。有没有一种方法可以在没有负面影响的情况下获得同步AJAX?是的,我意识到术语同步AJAX是一种矛盾修饰法。不。根据定义,同步就是阻塞。在流程完成之前,任何操作都无法继续。它包括web浏览器中UI的其余部分 它应该是异步的,所以最好的方法是设计异步工作的代码。我认为这是不可能的。您可以使用异步方法并使用ajaxdone事件,而不是尝试使用同步查

有没有一种方法可以执行不冻结浏览器的同步AJAX查询?在我看来,在大多数情况下,使用同步请求要容易得多,但它们阻止代码的其他部分执行的事实是一个真正的杀手。有没有一种方法可以在没有负面影响的情况下获得同步AJAX?是的,我意识到术语同步AJAX是一种矛盾修饰法。

不。根据定义,同步就是阻塞。在流程完成之前,任何操作都无法继续。它包括web浏览器中UI的其余部分


它应该是异步的,所以最好的方法是设计异步工作的代码。

我认为这是不可能的。您可以使用异步方法并使用ajaxdone事件,而不是尝试使用同步查询

使用jQuery.ajax的示例

jQuery.ajax({
    url: "URL HERE",
    data: "whatever you are sending"
}).done(function (data) {
    // Do things with data
});

因此,您可以使用异步请求,而不是使用同步请求,并在请求完成后执行代码。所以,它不会冻结你的浏览器

我将举例说明允许这种行为的不良副作用

假设您有此程序:

<script>
var file = "foo.json";

function nullIt() {
    file = null;
}

function loadFile() {
    if (file != null) {
        synchronousLoad(file);//imagine the load takes 5 seconds
        alert("i just loaded: " + file);
    }
}

window.onload = loadFile;
</script>
<button onclick="nullIt()">click me</button>
这里的坏事是-

当synchronousLoad阻塞5秒钟时,用户单击按钮,事件处理程序将快速运行完成。 现在文件变量为空。 synchronousLoad完成并返回,让执行在下一行代码上继续 但是文件现在为空,并且向用户输出的消息被中断。 这里的真正问题是,您不能再以同样的方式对代码进行推理。只是因为一些事实 第五行为真,但并不意味着下一行仍为真。这使得编写一个无错误的程序非常困难

有些编程语言支持多线程,您必须处理这些问题,尽管您有工具来帮助处理这些问题。 但是,程序员仍然需要付出很多额外的努力


相对而言,使用回调来执行异步操作是ez模式。

出于其他答案中概述的原因,如果不阻止浏览器中的其他事件,则无法执行同步AJAX调用

但是,如果代码复杂性是您希望避免异步方法调用的主要原因,那么您可能会对Javascript交叉编译器感兴趣,它允许您像同步一样编写异步方法调用,并像异步编写调用一样获得相同的结果

从项目的GitHub页面:

streamline.js是一种简化异步Javascript的语言工具 编程

而不是编写毛茸茸的代码,如:

function archiveOrders(date, cb) {
  db.connect(function(err, conn) {
    if (err) return cb(err);
    conn.query("select * from orders where date < ?", [date], function(err, orders) {
      if (err) return cb(err);
      helper.each(orders, function(order, next) {
        conn.execute("insert into archivedOrders ...", [order.id, ...], function(err) {
          if (err) return cb(err);
          conn.execute("delete from orders where id=?", [order.id], function(err) {
            if (err) return cb(err);
            next();
          });
        });
      }, function() {
        console.log("orders have been archived");
        cb();
      });
    });
  });
}
你写道:

function archiveOrders(date, _) {
  var conn = db.connect(_);
  conn.query("select * from orders where date < ?", [date], _).forEach_(_, function(_, order) {
    conn.execute("insert into archivedOrders ...", [order.id, ...], _);
    conn.execute("delete from orders where id=?", [order.id], _);
  });
  console.log("orders have been archived");
}
简化代码转换并处理回调

无需学习控制流API!你只需要遵循一个简单的规则:

用下划线替换所有回调,并将代码编写为 功能是同步的


有关streamline.js的更多信息,请阅读博文。

在即将发布的ECMAScript 2016 ES7标准中,有一组新的语言关键字,其设计与您似乎正在寻找的内容非常相似,称为async和await

这些关键字不允许非阻塞同步AJAX,但它们允许您以看起来同步的方式编写异步代码。下面是一个简单的例子:

// Let's say you have an asynchronous function that you want to call in a synchronous
// style...
function delayedEval(delay, func) {
  // First, ensure that the function returns a Promise object. If it doesn't, wrap it with
  // another function that does.
  return new Promise((resolve, reject) => {
    setTimeout(() => resolve(func()), delay)
  })
  // For more on Promises, see https://goo.gl/uaoDuy (MDN link)
}

// Then, declare a function as asynchronous. This causes it to return a Promise that 
// resolves to its return value, instead of returning its return value directly.
async function delayedHello() {
  // Inside an async function, you can call other async functions like this, which looks
  // very much like a synchronous call (even though it isn't).
  let message = await delayedEval(1500, () => "Hello, world!")
  console.log(message)
}

// This returns (a Promise) immediately, but doesn't print "Hello, world!" until 1.5
// seconds later. (At which point it resolves the Promise.)
delayedHello()
基本上,与没有负面影响的同步AJAX不同,async和await让您获得没有负面影响的异步AJAX。混乱的代码,有很多处理回调的逻辑


async和await是ES7标准中的一部分。

我不这么认为。。。我建议您学习承诺,让使用AJAX更容易。@对不起,我想这是措词不当的。我的意思是,它不会冻结浏览器或阻止我代码中的其他事件触发。即使非阻塞同步不是矛盾,在单执行(也称为单线程环境)中也不可能实现这种构造。另一种选择,实际上是浏览器JavaScript中的解决方案,是非阻塞异步的。相关:在这里也可能有帮助:是的,但这正是我通过执行同步请求试图避免的。在我的代码的当前执行路径中,没有任何东西需要在请求完成之前执行,因此只执行一个同步请求似乎更干净。我只是不希望它在等待时阻止我代码的其他部分。@Ajedi32它一点也不干净——特别是因为它不能处理单一的执行上下文,比如浏览器JavaScript使用的执行上下文。此外,当使用多个执行上下文(即线程或甚至连续)时,还需要处理其他注意事项和问题:删除隐式原子执行,并且必须防止[更多形式的]竞争条件。@AJED32在中使用承诺
特别是,在jQuery1.8+中实现并由编码可以极大地清除异步代码的使用。我发现promises模型比以前的成功/错误回调更加一致和干净。啊,非常好。就我个人而言,如果你可以这么说的话,我更愿意在这样的比赛条件下冒险,但是很高兴看到一些理由来解释为什么事情是这样的。