承诺是一个概念。这是关于 AngularJS Promises 的一个问题,它与其他 Promises 有点不同,但跨库的概念基本相同。
什么是异步进程?
如果你知道这是什么,请跳过它并阅读下一个标题,否则:
当你有代码时,它通常按顺序运行,如下所示:
object.method() // First,
variable = "something"; // Second,
for(var i=0; i<2; i++) {
resp = object.makeHttpRequest();
console.log(resp.data + " was #" + i);
} // Third,
console.log("Done"); // Last.
每个步骤都在前一个完成之后执行。当for 循环需要很长时间(想象一下HTTP 请求需要很长时间)时,这可能是一个问题。该请求将挂起整个进程,直到 HTTP 请求完成。非常糟糕。
Node.js 默认使用 回调模式 处理此问题。当您调用一个阻塞的函数(需要很长时间,例如读取磁盘上的文件或发出 HTTP 请求)时,您注册了一个 回调函数,它将在之后调用精加工。它会apply 该函数使用来自阻塞函数的数据当它完成时。这允许您在该阻塞函数完成时运行其他代码。
正如许多 Node.js 开发人员会告诉您的那样,这段代码可能会变得非常混乱,速度非常快。相反,AngularJS(和其他库)会在代码完成时返回一个 Promise。它允许您使用Promise Pattern。
我知道什么是异步的东西
Promise 在概念上类似于回调,但更简洁并且允许更大程度的控制。考虑一下:
var url = getUrlFunction();
makeHttpRequest(url, function onResponse(data) {
dataHandler(data);
console.log("done");
}, function onError(err) {
errHandler(err);
console.log("uh oh");
});
showTheUserWeAreLoading();
// Or in node.js
var url = getUrlFunction();
makeHttpRequest(url, function onResponse(err, data) {
(err) ? handleErr(err): null;
dataHandler(data);
console.log("done");
});
showTheUserWeAreLoading();
showTheUserWeAreLoading 函数会(有时)在 HTTP 请求完成之前发生,这不是很直观。在重新阅读您自己的代码时,这还有很多不足之处。
相同的代码,但使用 makeHttpRequest 返回一个承诺:
var url = getUrlFunction(), prom = makeHttpRequest(url);
showTheUserWeAreLoading();
prom.then(function onSuccess(data) {
dataHandler(data);
console.log("done");
}, function onError(err) {
errHandler(err);
console.log("uh oh");
});
promise 对象有助于跟踪操作的状态。当操作达到以下两种状态之一时,您可以分配处理程序:已完成或已拒绝。
需要注意的是makeHttpRequest是AngularJS中$http()或jQuery中$.ajax的替代。在创建 Promise 标准之前in the ECMAScript standard,每个库(和库版本)对您应该/可以使用哪种模式都有自己的看法。 AngularJS 以前使用 .success(<function>).error(<function>) 命名模式,而 jQuery 使用 .done(<function>).fail(<function>)。这些命名方案在很久以前就被贬低了,因此库之间的当前差异不明显(感谢 ECMAScript)。