异步
我见过很多地方在异步(异步)的词,但当我仍然不能理解这个概念,但
发现自己
经常清楚(***)。
如果你有类似的
情况,那也没关系。
搜索这个词,你可以得到一般的描述。在这里,我将对Javascript的异步性做一点额外的解释。
看看这个代码:
var开始=新
日期();
setTimeout(){()
函数(
var结束=新日期();
console.log(时间:
},500);
当(新日期,开始< 1000){ };
此代码将得到一个类似时间:1013ms
运行后,
设置setTimeout函数()在未来500ms实际上比1000ms更多时间后
执行。
你怎么解释呢当setTimeout()被称为延迟事件排队。然后,继续在这个执行代码,和以后的代码,直到没有代码。没有任何代码,Javascript
线程空闲时。此时,Javascript执行引擎只查看队列,查找应该在队列中触发的事件,然后调用事件的
处理器(函数)。当执行处理器时,它再次返回队列,然后查看下一个事件。
单线程的Javascript在队列的形式的作品,在一个活动周期的形式。所以,在前面的代码,我们使用同时拖动执行引擎为1000ms的代码的运行过程中,并没有将之前的所有代码运行回到队列发生。这是Javascript异步机制。
javascript的异步问题
Javascript中的异步
操作可能并不总是容易做到的。
Ajax可能是我们使用过的最常用的异步操作,例如,在jQuery中,
启动Ajax请求的代码通常是这样的:
对代码的ajax请求
$ ajax({
网址,
数据:数据对象,
成功:(函数){ },
错误:(函数){ }
});
这种写作方式有什么问题吗简单地说,这还不够光,为什么我们必须把成功和错误写回到请求开始的地方呢如果我的回调会做很多事情,我会想到一件事,然后回到这里添加代码吗
例如,我们想完成这样一个事情:有4个访问ajax URL
地址,ajax需要先访问,在访问完成后首先接收到返回的数据作为
参数访问第二个,第二次访问完成后第三到4…完成所有访问。这样,它看起来像这样。
$ ajax({
网址:url1,
成功:函数(数据){
$ ajax({
网址:url2,
数据:数据,
成功:函数(数据){
$ ajax({
…
});
}
});
}
})
你会发现代码被称为金字塔的厄运(金字塔厄运)看起来很可怕。它有可能用于回调直接添加,而不可能从一个传递到下一个异步事件的回调函数。命名和分离这些回调函数可以减少表格嵌套,使代码清晰,但仍不能
解决问题。
另一个常见的困难是在同一时间发送两个Ajax请求,然后在成功返回两个请求后执行以下操作。如果你想添加回调每个呼叫的地方只有在前面的路,这也有点难吗
适合于这些异步操作,可以使您编写更优雅的代码承诺。
承诺
什么是承诺作为以前jQuery的Ajax请求代码的一个例子,代码实际上可以编写为:
var允诺=
网址,
数据:数据对象
});
promise.done(function(){ });
promise.fail(function(){ });
这相当于以前的Ajax请求代码。正如您所看到的,添加承诺会使代码格式发生变化。Ajax请求被
保存,就像赋值变量一样。这就是封装,而封装将真正使异步事件更容易。
封装是有用的
允诺对象就像一个
打包的异步事件引用。您想在异步事件完成后做一些事情吗添加一个回调到它,不管你有多少额外的问题。
jQuery的Ajax
方法返回一个对象(这是承诺,是突出的特征jquery1.5)。如果我有完成的两个函数()和氧()执行后的异步事件顺利完成,就是做这个的:
promise.done(干);
这里的代码。 /其他
promise.done(DO2);
这是更自由的。只要我把这个承诺的对象,我添加任意数量的回调代码在任何时候当我写的代码,没有考虑到异步事件开始,承诺的优势。
正式的
介绍 承诺是响应异步操作,它的发展为CommonJS规范非常有用,所谓的承诺/ a.promise代表一个操作结束后操作的返回值,其中有3个国家:
承诺的成功是肯定的(完成或解决的)。
否定(拒绝或失败)表明承诺的操作失败。
等待(待定),尚未取得肯定或否定的结果,继续进行。
此外,有1种名义上的国家用来表示承诺的成功或失败,也就是说,肯定和否定状态的集合称为终结(承诺),允诺也有以下重要特征:
承诺只能从等待状态变为正态或负状态,一旦转化为正态或负态,它就永远不会改变它的状态。
如果在一个承诺完成后成功地将回调添加到成功或失败(根据前面的描述成功或失败),回调函数将立即执行。
考虑Ajax操作,启动一个请求,等待,然后返回或发生错误(失败),这是否与承诺一致
承诺的特点作进一步的解释,是一个很好的例子:jQuery的$(document)。准备(onready),onready回调函数将在DOM就绪,执行,但有趣的是,如果DOM准备好之前执行此代码,onready将立即无任何延迟执行(即
同步)。
承诺的例子
生成的承诺
承诺/ A列出了一系列实现承诺的Javascript库,jQuery就在其中:
递延值=递延();
deferred.done(
功能(
消息){ console.log(:+消息)});
deferred.resolve(桑); / /:桑色素
jQuery本身定义了一类称为递延,这实际上是承诺。美元。
延期()方法返回一个新生成的承诺情况。一方面,它采用deferred.done(),()deferred.fail添加回调它。另一方面,它要求deferred.resolve deferred.reject()或()来证实或否认这种承诺,可以
传输任何数据回调。
合并的承诺
还记得我在同时发送2个Ajax请求时所说的问题吗以jQuery为例,承诺将能够以这种方式解决它:
VaR生机勃勃=美元。Ajax(url1),
promise2 =美元。Ajax(url2),
promisecombined =美元。当(生机勃勃,promise2);
promisecombined.done(ondone);
方法可以合并多个承诺以获得一个新的承诺,如果承诺的所有组成部分都成功了,则在原有的多重承诺和(逻辑和)关系之间等价,这样在合并承诺成功后,如果有任何承诺失败,在承诺失败后立即合并。
级联的承诺
依次继续我以前的一系列异步
任务,它将使用最重要的。然后()承诺方法(在承诺/规范中,也可以用一个随后的()方法定义一个对象的承诺):
VaR的承诺=美元。Ajax(url1);
承诺= promise.then(功能(数据){
返回阿贾克斯(url2、数据);
});
承诺= promise.then(功能(数据){
返回Ajax(url3,数据);
});
…
当时承诺的完全形式()方法,然后(ondone,onfail,进步)。所以看起来它是一个简单的方法可以一次添加各种回调。是的,你可以使用它,这是等价的。
但是,.()方法还有一个更有用的功能,就像这个词本身的意思一样,它被用来清楚地指定异步事件的前后关系:第一次,然后(然后),这叫做承诺的级联。
级联的承诺,重要的是要注意,在回调函数中通过()后,有必要回到你想表示下一个任务的承诺,如美元。Ajax(url2、数据)上述代码。这样,变量是分配给前将成为一个新的承诺。如果当时()回调函数返回的不是承诺,然后,然后()方法返回原来的承诺。
我应该觉得很难理解吗从代码执行的角度来看,上面的多段()代码实际上是由Javascript引擎完成的,但它就像是在舞台剧中编写的
脚本。在阅读完它之后,Javascript引擎将安排参与者在将来玩,而
性能是异步的,然后()方法是允许编写异步脚本的笔。
在回调函数的基础上使用API中的承诺
美元。Ajax()方法反复使用在以前的文章中会返回一个承诺的对象,这实际上是通过jQuery提供了效益。现实情况是,大多数的Javascript API,包括Node.js本土的功能,是基于回调函数,不承诺为基础的。在这种情况下,承诺的使用需要自己做一些处理。
这个处理实际上比较简单直接,下面是一个例子:
递延值=递延();
setTimeout(deferred.resolve,1000);
deferred.done(ondone);
这样,承诺的肯定或否定触发器,作为API的回调,变成了承诺的处理
模式。
诺言是怎么实现的
在这篇文章中,承诺中,您已经找到了基于承诺的所有已实现的库,那么,如果您希望自己构建一个承诺,该怎么办呢
承诺库中的第一个q可以是承诺/规范的最一致和最直观的实现。如果你想知道如何做出承诺,你可以
参考Q提供的设计模式解析。
限于
空间,本文仅介绍了承诺的适用,我将在将来单独撰写一篇文章,
详细说明承诺的实施细节。
由于Javascript的后续版本,ECMAscript 6将提供保证人。如果您想了解它的用法,我们建议您阅读Javascript的承诺:一遍又一遍。
后记
承诺这个词不适合
翻译,但同时也是有道理的,然而,它在用Javascript执行更复杂的异步任务时确实提供了相当大的帮助。