vuikit
Version:
A responsive Vue UI library for web site interfaces based on UIkit
198 lines (164 loc) • 4.03 kB
JavaScript
/**
* Copyright (c) 2013-2018 YOOtheme GmbH, getuikit.com
*/
/* eslint-disable one-var, no-useless-call */
/* setImmediate */
import {isFunction, isObject} from './lang'
export const win = typeof window !== 'undefined' && window
export const Promise = win && 'Promise' in window ? window.Promise : PromiseFn
export class Deferred {
constructor () {
this.promise = new Promise((resolve, reject) => {
this.reject = reject
this.resolve = resolve
})
}
}
/**
* Promises/A+ polyfill v1.1.4 (https://github.com/bramstein/promis)
*/
const RESOLVED = 0
const REJECTED = 1
const PENDING = 2
const async = win && 'setImmediate' in window ? setImmediate : setTimeout
function PromiseFn (executor) {
this.state = PENDING
this.value = undefined
this.deferred = []
const promise = this
try {
executor(
x => {
promise.resolve(x)
},
r => {
promise.reject(r)
}
)
} catch (e) {
promise.reject(e)
}
}
PromiseFn.reject = function (r) {
return new PromiseFn((resolve, reject) => {
reject(r)
})
}
PromiseFn.resolve = function (x) {
return new PromiseFn((resolve, reject) => {
resolve(x)
})
}
PromiseFn.all = function all (iterable) {
return new PromiseFn((resolve, reject) => {
const result = []
let count = 0
if (iterable.length === 0) {
resolve(result)
}
function resolver (i) {
return function (x) {
result[i] = x
count += 1
if (count === iterable.length) {
resolve(result)
}
}
}
for (let i = 0; i < iterable.length; i += 1) {
PromiseFn.resolve(iterable[i]).then(resolver(i), reject)
}
})
}
PromiseFn.race = function race (iterable) {
return new PromiseFn((resolve, reject) => {
for (let i = 0; i < iterable.length; i += 1) {
PromiseFn.resolve(iterable[i]).then(resolve, reject)
}
})
}
const p = PromiseFn.prototype
p.resolve = function resolve (x) {
const promise = this
if (promise.state === PENDING) {
if (x === promise) {
throw new TypeError('Promise settled with itself.')
}
let called = false
try {
const then = x && x.then
if (x !== null && isObject(x) && isFunction(then)) {
then.call(
x,
x => {
if (!called) {
promise.resolve(x)
}
called = true
},
r => {
if (!called) {
promise.reject(r)
}
called = true
}
)
return
}
} catch (e) {
if (!called) {
promise.reject(e)
}
return
}
promise.state = RESOLVED
promise.value = x
promise.notify()
}
}
p.reject = function reject (reason) {
const promise = this
if (promise.state === PENDING) {
if (reason === promise) {
throw new TypeError('Promise settled with itself.')
}
promise.state = REJECTED
promise.value = reason
promise.notify()
}
}
p.notify = function notify () {
async(() => {
if (this.state !== PENDING) {
while (this.deferred.length) {
const [onResolved, onRejected, resolve, reject] = this.deferred.shift()
try {
if (this.state === RESOLVED) {
if (isFunction(onResolved)) {
resolve(onResolved.call(undefined, this.value))
} else {
resolve(this.value)
}
} else if (this.state === REJECTED) {
if (isFunction(onRejected)) {
resolve(onRejected.call(undefined, this.value))
} else {
reject(this.value)
}
}
} catch (e) {
reject(e)
}
}
}
})
}
p.then = function then (onResolved, onRejected) {
return new PromiseFn((resolve, reject) => {
this.deferred.push([onResolved, onRejected, resolve, reject])
this.notify()
})
}
p.catch = function (onRejected) {
return this.then(undefined, onRejected)
}