Last active
August 29, 2015 14:07
-
-
Save weirongxu/0e9101e77611a2b234d3 to your computer and use it in GitHub Desktop.
angular $q queue
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'app' | |
.factory 'Promise', [ | |
'$q' | |
( | |
$q | |
)-> | |
# $q 和 Promise 都兼容的方法 | |
# @example 1) | |
# new Promise (resolve, reject, notify)-> | |
# if flag | |
# resolve true | |
# else | |
# reject false | |
# @example 2) FIXME | |
# new Promise -> | |
# if flag | |
# @resolve true | |
# else | |
# @reject false | |
# | |
# @example 3) | |
# Promise (resolve, reject, notify)-> | |
# if flag | |
# resolve true | |
# else | |
# reject false | |
# | |
# @example 4) FIXME | |
# Promise -> | |
# if flag | |
# @resolve true | |
# else | |
# @reject false | |
# @example 5) | |
# deferral = Promise.defer() | |
# if flag | |
# deferral.resolve true | |
# else | |
# deferral.reject true | |
# deferral.promise | |
p = (fn) -> | |
deferred = $q.defer() | |
fn.notify = (args...)-> | |
deferred.notify args... | |
fn.resolve = (args...)-> | |
deferred.resolve args... | |
fn.reject = (args...)-> | |
deferred.reject args... | |
fn fn.resolve, fn.reject, fn.notify | |
@then = (args...)-> | |
deferred.promise.then args... | |
@catch = (args...)-> | |
deferred.promise.catch args... | |
@finally = (args...)-> | |
deferred.promise.finally args... | |
deferred.promise | |
p.defer = ()-> | |
$q.defer() | |
p.resolve = (args...)-> | |
$q.when args... | |
p.when = (args...)-> | |
$q.when args... | |
p.reject = (reason)-> | |
deferred = $q.defer() | |
deferred.reject reason | |
deferred.promise | |
p.all = (promises)-> | |
$q.all promises | |
# TODO | |
# p.allSettled = (promises)-> | |
# # 同kriskowal/q的allSettled | |
# # Q.allSettled(promises).then (results) -> | |
# # results.forEach (result) -> | |
# # if result.state is 'fulfilled' | |
# # value = result.value | |
# # else | |
# # reason = result.reason | |
p.anyall = (promises)-> | |
# 与$q.all不同的方法 | |
# 在碰到reject时, 赋值为null, 并不中止. | |
deferred = $q.defer() | |
counter = 0 | |
results = (if angular.isArray(promises) then [] else {}) | |
resolve = (key, value)-> | |
if results.hasOwnProperty(key) | |
return | |
results[key] = value | |
unless --counter | |
deferred.resolve results | |
angular.forEach promises, (promise, key) -> | |
counter++ | |
$q.when(promise).then (value) -> | |
resolve key, value | |
, (reason) -> | |
resolve key, null | |
if counter is 0 | |
deferred.resolve results | |
deferred.promise | |
# TODO | |
# p.race = (promises)-> | |
# p.spread | |
# 队列方式去执行promise, | |
# 让promise执行方式为非异步, | |
# 防止获取重复的数据 | |
# | |
# @example 简单示例 | |
# Promise.queue promies, (promise)-> | |
# return Promise.resolve promise | |
# , (data, key, promises)-> | |
# console.log 'success' | |
# true | |
# , (reason, key, promises)-> | |
# console.log 'error' | |
# true | |
# .then (datas)-> | |
# console.log 'success' | |
# .catch (reasons)-> | |
# console.log 'success' | |
# | |
# @example 队列方式去获取用户信息 | |
# _user = {} # 用户缓存数组, 这样就不会重复获取Levi | |
# Promise.queue ['Jang', 'Levi', 'Kirito', 'Asuna', 'Levi', 'Levi'], (username)-> | |
# if username of _user | |
# return Promise.resolve _user[username] | |
# # 等于 return $q.when _user[username] | |
# else | |
# return $http.get '/username/#{username}' | |
# , (user, key, usernames)-> | |
# console.log "#{usernames[key]}'s info as follow" | |
# console.dir user | |
# true | |
# , (reason)-> | |
# console.log 'error' | |
# true | |
# .then (users)-> | |
# console.table users | |
# .catch (reasons)-> | |
# console.log reason | |
# | |
# @param promise_array [Array] | |
# 数组 (可以是一般数据 或 primise) | |
# | |
# @param getPromise [Function] 同步队列本体 | |
# Function(promise) | |
# @param promise [mixin] 来自promise_array | |
# @return [Promise] 返回用于同步执行的Promise, 返回false表示忽略这个promise. | |
# | |
# @param success [Function] | |
# Function(data, key, promise_array) | |
# @param data 每次获取到的数据 | |
# @param key 每次获取到的元值索引 | |
# @param promise_array 源数组 | |
# @return [Boolean] 返回false终止运行, 并调用reject | |
# | |
# @param error [Function] | |
# Function(data, key, source_promise) | |
# @param data reject后获取到的reason | |
# @param key 每次获取到的元值索引 | |
# @param promise_array 源数组 | |
# @return [Boolean] 返回false终止运行, 并调用reject | |
p.queue = (promise_array, getPromise, success=null, error=null)-> | |
deferred = $q.defer() | |
p.anyall promise_array | |
.then (items)-> | |
resolves = [] | |
reasons = [] | |
stack = [] | |
for value, key in items | |
stack.push | |
key: key | |
value: value | |
do recursion = -> | |
if item = stack.shift() | |
if (promise = getPromise item.value) isnt false | |
promise.then (value)-> | |
resolves.push value | |
if not success || success(value, item.key, items) | |
recursion() | |
else | |
deferred.reject reasons | |
, (reason)-> | |
reasons.push reason | |
if not error || error(reason, item.key, items) | |
recursion() | |
else | |
deferred.reject reasons | |
else | |
recursion() | |
else | |
if reasons.length | |
deferred.reject reasons | |
else | |
deferred.resolve resolves | |
deferred.promise | |
p | |
] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment