promise是什么
这里不诠释promise是什么,由于我相信你来看文章的时刻已晓得你什么是promise了。
此处有promise范例。
Promise/A+范例 中文
Promise/A+
ES2016:MDN Promise
$q
$q是AngularJS供应的一个效劳。
$q是跟AngularJS的$rootScope模板集成的,所以在AngularJS中实行和谢绝都很快。(编辑器疯了,dollar标记就是打不出来,就叫 ‘dollar’q)
$q是跟AngularJS模板引擎集成的,这意味着在视图中找到任何Promise都邑在视图中被实行或许谢绝。
如安在AngularJS中运用
直接上栗子,程序员都不喜好听你空话~〒▽〒
var app = angular.module('app', [])
.controller('testController', function ($scope, $q) {
//定义一个defer
var defer = $q.defer();
var promise = defer.promise;
promise.then(function (data) {
//胜利后的逻辑处置惩罚
}, function (error) {
//失利后的逻辑处置惩罚
});
//模仿经由过程--现实应该是一个异步的callback中挪用
defer.resolve('[data]');
//模仿谢绝--现实应该是一个异步的callback中挪用
defer.reject('[data]');
});
链式挪用
then会返回一个新的promise对象,所以直接jQuery作风的链式挪用。
照样直接上栗子:
var app = angular.module('app', [])
.controller('testController', function ($scope, $q) {
//定义一个defer
var defer = $q.defer();
var promise = defer.promise;
promise.then(function () {
console.log('then-resolved-1');
}, function () {
console.log('then-rejected-1');
})
.then(function () {
console.log('then-resolved-2');
}, function () {
console.log('then-rejected-2');
});
//模仿经由过程--现实应该是一个异步的callback中挪用
defer.resolve('[data]');
//模仿谢绝--现实应该是一个异步的callback中挪用
defer.reject('[data]');
});
来看下是怎样完成链式挪用的,下面是AngularJS源码完成:
//angular.js
Promise.prototype = {
then: function(onFulfilled, onRejected, progressBack) {
var result = new Deferred();//此处能够看出,每一个then都邑返回一个新的Deferred对象。
this.$$state.pending = this.$$state.pending || [];
this.$$state.pending.push([result, onFulfilled, onRejected, progressBack]);
if (this.$$state.status > 0) scheduleProcessQueue(this.$$state);
return result.promise;
},
//其他省略
...
}
//Deferred定义
function Deferred() {
this.promise = new Promise();//能够看到defer的promise对象是一个new Promise()
//Necessary to support unbound execution :/
this.resolve = simpleBind(this, this.resolve);
this.reject = simpleBind(this, this.reject);
this.notify = simpleBind(this, this.notify);
}
链式挪用参数通报
看过上面链式挪用的栗子和AngularJS的源码后,人人就可以晓得每一个then的上下文现实上是不一样的,由于每次都是新new 出来的Promise对象。
先给栗子:
var app = angular.module('app', [])
.controller('testController', function ($scope, $q) {
//定义一个defer
var defer = $q.defer();
var promise = defer.promise;
promise.then(function (data) {
//...
return data;// data = 1
}, function (error) {
//...
})
.then(function (data) {
//...
return data;//data = 1
}, function (error) {
//...
});
//模仿经由过程--现实应该是一个异步的callback中挪用
defer.resolve('1');
});
接下来看一段源码剖析,看看AngularJS是怎样挪用Promise的。
//angular.js
Deferred.prototype = {
resolve: function(val) {
if (this.promise.$$state.status) return;
if (val === this.promise) {
this.$$reject($qMinErr(
'qcycle',
"Expected promise to be resolved with value other than itself '{0}'",
val));
}
else {
this.$$resolve(val);//现实挪用这个要领
}
},
$$resolve: function(val) {
var then, fns;
fns = callOnce(this, this.$$resolve, this.$$reject);
try {
if ((isObject(val) || isFunction(val))) then = val && val.then;
if (isFunction(then)) {
this.promise.$$state.status = -1;
then.call(val, fns[0], fns[1], this.notify);
} else {
this.promise.$$state.value = val;
this.promise.$$state.status = 1;
scheduleProcessQueue(this.promise.$$state);//终究在此处加入到行列中
}
} catch (e) {
fns[1](e);
exceptionHandler(e);
}
},...
//scheduleProcessQueue定义
function scheduleProcessQueue(state) {
if (state.processScheduled || !state.pending) return;
state.processScheduled = true;
nextTick(function() { processQueue(state); });//此处挪用进入processQueue
}
function processQueue(state) {
var fn, promise, pending;
pending = state.pending;
state.processScheduled = false;
state.pending = undefined;
for (var i = 0, ii = pending.length; i < ii; ++i) {
promise = pending[i][0];
fn = pending[i][state.status];
try {
if (isFunction(fn)) {
promise.resolve(fn(state.value));//此处是链式挪用传参症结,fn(state.value)现实是上一个then的resolve的返回值,所以能晓得,假如须要一切的then都能取到异步使命的返回值,就得在then的resolve函数中,将值返回。
} else if (state.status === 1) {
promise.resolve(state.value);
} else {
promise.reject(state.value);
}
} catch (e) {
promise.reject(e);
exceptionHandler(e);
}
}
}