Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于Promise的用法(基础篇) #32

Open
yangbiaolong opened this issue Sep 6, 2016 · 0 comments
Open

关于Promise的用法(基础篇) #32

yangbiaolong opened this issue Sep 6, 2016 · 0 comments

Comments

@yangbiaolong
Copy link

yangbiaolong commented Sep 6, 2016

一. $q的构成

  • defer
    • promise
      • then(successCallback, [errorCallback], [notifyCallback]):successCallback为完成promise的回调方法,errorCallback为失败时的回调方法,notifyCallback为通知时的回调方法
      • catch(errorCallback):promise.then(null, errorCallback)方法的简写
      • finally(callback, notifyCallback):无论promise被resolve还是reject,都会调用callback方法,但是该方法是没有参数的,如果是链式调用的话,会继续使用该promise被resolve或者reject所传入的值向后传递
    • resolve(value):完成promise调用这个方法,value会被当做参数传入对应的方法
    • reject(reason):失败时调用这个方法,reason会被当做参数传入对应的方法
    • notify(value):通知的时候调用,可以调用零次或者多次,必须在调用resolve或者reject之前调用
  • reject(reason):返回一个已经调用过将reason作为参数的reject方法的promise
  • when(value, [successCallback], [errorCallback], [progressCallback]):该方法返回新的promise,执行该promise的resolve方法,以value作为参数,并将 successCallback, errorCallback, progressCallback作为参数调用then方法作为返回值
  • resolve(value, [successCallback], [errorCallback], [progressCallback]):when方法的别名,为了和ES6的命名标尺一致
  • all(promises):该方法通过传入promises这个promise数组或者对象的集合,当全部的promise完成时,才会调用resolve方法,并将该promises数组或者对象的reslove结果包装成对应的数组或者对象作为参数;只要数组或者对象的一个promise失败,就会调用该reject方法,并将该promise的reson作为参数
  • race(promises):该方法通过传入promises这个promise数组或者对象的集合,只要数组或者对象的一个promise完成或者失败,就会调用resolve或者reject,并传入对应的参数

二. 用法

1.像ES6标准的Promise的用法一样的构造器风格:

  • $q(resolver):resolver格式为function(function, function),返回值为Promise;resolver的第一个参数是一个解决(resolve)Promise的方法,第二个参数是一个拒绝(reject)Promise的方法;
  • 例子:
function asyncGreet(name) {
    // perform some asynchronous operation, resolve or reject the promise when appropriate.
    return $q(function(resolve, reject) {
        setTimeout(function() {
            if (okToGreet(name)) {
                resolve('Hello, ' + name + '!');
            } else {
                reject('Greeting ' + name + ' is not allowed.');
            }
        }, 1000);
    });
}   
var promise = asyncGreet('Robin Hood');
promise.then(function(greeting) {
    alert('Success: ' + greeting);
}, function(reason) {
    alert('Failed: ' + reason);
});    
  • 注意 :
    1. 该用法不支持progress/notify回调用法
    2. 在resolver这个构造方法里抛出的异常,并不会自动调用该Promise的reject方法

2. 传统的CommonJS-style用法:

  • 通过$q.defer()方法新建一个Defer对象,该对象带有promise属性,和resolve、reject和notify方法,然后在合适的时候调用这三个方法,就会调用promise的对应回调函数
  • 例子:
function asyncGreet(name) {
  var deferred = $q.defer();

  setTimeout(function() {
    deferred.notify('About to greet ' + name + '.');

    if (okToGreet(name)) {
      deferred.resolve('Hello, ' + name + '!');
    } else {
      deferred.reject('Greeting ' + name + ' is not allowed.');
    }
  }, 1000);

  return deferred.promise;
}

var promise = asyncGreet('Robin Hood');
promise.then(function(greeting) {
  alert('Success: ' + greeting);
}, function(reason) {
  alert('Failed: ' + reason);
}, function(update) {
  alert('Got notification: ' + update);
});

注意 :

  • then、catch、finally方法不是必须在调用defer的resolve方法和reject方法之后才能调用(notifyCallback方法除外,该方法必须先绑定回调方法,才能通过notify方法调用,否则不会调用notifyCallback方法)
  • then、catch、finally方法一定是异步的,哪怕直接调用resolve方法或者reject方法
  • then、catch方法参数里的回调函数都只会被传入一个参数;finally方法的callback回调函数不会被传入参数,notifyCallback回调函数只会被传入一个参数
  • defer的resolve和reject方法一共只能被调用一次,之后的调用将不起作用
  • notify函数在调用resolve方法或者reject方法之前可以调用零次或者多次,之后的调用将不起作用

三.$q和Kris Kowal's Q的差异

  1. $q因为基于$rootScope.Scope作用域模型检查机制构建的,所以它可以更快的把解决或者拒绝的结果更新到你的models里,避免不必要的浏览器重绘(会导致UI闪烁)
  2. Q比$q拥有更多的功能特性,但带来的是代码字节数的增加。 $q很轻量级,但包含了一般异步任务所需的所有重要功能
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants