/** * Provide a callback to be called whenever this promise is rejected * * @param {OnFailCallbackType} onFail * @return {!Promise} returns a new promise with the output of the onFail handler */Promise.prototype.fail=function(onFail){returnthis.then(null, onFail)}

/** * Provide a callback to be called whenever this promise is either resolved * or rejected. * * @param {function()} onComplete * @return {!Promise} returns the current promise */Promise.prototype.fin=function(onComplete){if(this._hasData ||this._error){ onComplete()returnthis}

/** * Mark this promise as "ended". If the promise is rejected, this will throw an * error in whatever scope it happens to be in * * @return {!Promise} returns the current promise */Promise.prototype.end=function(){if(this._error){throwthis._error}this._ended =truereturnthis}

/** * Return a new promise that behaves the same as the current promise except * that it will be rejected if the current promise does not get fulfilled * after a certain amount of time. * * @param {number} timeoutMs The timeout threshold in msec * @param {string=} timeoutMsg error message * @returns a new promise with timeout */ Promise.prototype.timeout=function(timeoutMs, timeoutMsg){var deferred =new Promise()var isTimeout =false

/** * Return true iff the given object is a promise of this library. * * Because kew's API is slightly different than other promise libraries, * it's important that we have a test for its promise type. If you want * to test for a more general A+ promise, you should do a cap test for * the features you want. * * @param {*} obj The object to test * @return {boolean} Whether the object is a promise */function isPromise(obj){return!!obj._isPromise}

/** * Takes in an array of promises or literals and returns a promise which returns * an array of values when all have resolved. If any fail, the promise fails. * * @param {!Array.<!Promise>} promises * @return {!Promise} */function all(promises){if(arguments.length!=1||!Array.isArray(promises)){ promises = Array.prototype.slice.call(arguments,0)}if(!promises.length)return resolve([])

/** * Takes in an array of promises or literals and returns a promise which returns * an array of values when all have resolved or rejected. * * @param {!Array.<!Promise>} promises * @return {!Array.<Object>} The state of the promises. If a promise is resolved, * its corresponding state object is {state: 'fulfilled', value: Object}; * whereas if a promise is rejected, its corresponding state object is * {state: 'rejected', reason: Object} */function allSettled(promises){if(!Array.isArray(promises)){throw Error('The input to "allSettled()" should be an array of Promise')}if(!promises.length)return resolve([])

/** * Returns a promise that will be invoked with the result of a node style * callback. All args to fn should be given except for the final callback arg * * @param {function(...)} fn * @param {...} var_args a variable number of arguments * @return {!Promise} */function nfcall(fn, var_args){// Insert an undefined argument for scope and let bindPromise() do the work.var args = Array.prototype.slice.call(arguments,0) args.splice(1,0, undefined)return bindPromise.apply(undefined, args)()}