UNPKG

10.6 kBJavaScriptView Raw
1// This file contains all the non-ES6-standard helpers based on promise.
2
3module.exports = {
4
5 /**
6 * A function that helps run functions under a concurrent limitation.
7 * To run functions sequentially, use `yaku/lib/flow`.
8 * @param {Int} limit The max task to run at a time. It's optional.
9 * Default is `Infinity`.
10 * @param {Iterable} list Any [iterable](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Iteration_protocols) object. It should be a lazy iteralbe object,
11 * don't pass in a normal Array with promises.
12 * @return {Promise}
13 * @example
14 * ```js
15 * var kit = require('nokit');
16 * var all = require('yaku/lib/all');
17 *
18 * var urls = [
19 * 'http://a.com',
20 * 'http://b.com',
21 * 'http://c.com',
22 * 'http://d.com'
23 * ];
24 * var tasks = function * () {
25 * var i = 0;
26 * yield kit.request(url[i++]);
27 * yield kit.request(url[i++]);
28 * yield kit.request(url[i++]);
29 * yield kit.request(url[i++]);
30 * }();
31 *
32 * all(tasks).then(() => kit.log('all done!'));
33 *
34 * all(2, tasks).then(() => kit.log('max concurrent limit is 2'));
35 *
36 * all(3, { next: () => {
37 * var url = urls.pop();
38 * return {
39 * done: !url,
40 * value: url && kit.request(url)
41 * };
42 * } })
43 * .then(() => kit.log('all done!'));
44 * ```
45 */
46 all: require("./all"),
47
48 /**
49 * Similar with the `Promise.race`, but only rejects when every entry rejects.
50 * @param {iterable} iterable An iterable object, such as an Array.
51 * @return {Yaku}
52 * @example
53 * ```js
54 * var any = require('yaku/lib/any');
55 * any([
56 * 123,
57 * Promise.resolve(0),
58 * Promise.reject(new Error("ERR"))
59 * ])
60 * .then((value) => {
61 * console.log(value); // => 123
62 * });
63 * ```
64 */
65 any: require("./any"),
66
67 /**
68 * Generator based async/await wrapper.
69 * @param {Generator} gen A generator function
70 * @return {Yaku}
71 * @example
72 * ```js
73 * var async = require('yaku/lib/async');
74 * var sleep = require('yaku/lib/sleep');
75 *
76 * var fn = async(function * () {
77 * return yield sleep(1000, 'ok');
78 * });
79 *
80 * fn().then(function (v) {
81 * console.log(v);
82 * });
83 * ```
84 */
85 async: require("./async"),
86
87 /**
88 * If a function returns promise, convert it to
89 * node callback style function.
90 * @param {Function} fn
91 * @param {Any} self The `this` to bind to the fn.
92 * @return {Function}
93 */
94 callbackify: require("./callbackify"),
95
96 /**
97 * **deprecate** Create a `jQuery.Deferred` like object.
98 * It will cause some buggy problems, please don't use it.
99 */
100 Deferred: require("./Deferred"),
101
102 /**
103 * Creates a function that is the composition of the provided functions.
104 * See `yaku/lib/async`, if you need concurrent support.
105 * @param {Iterable} list Any [iterable](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Iteration_protocols) object. It should be a lazy iteralbe object,
106 * don't pass in a normal Array with promises.
107 * @return {Function} `(val) -> Promise` A function that will return a promise.
108 * @example
109 * It helps to decouple sequential pipeline code logic.
110 * ```js
111 * var kit = require('nokit');
112 * var flow = require('yaku/lib/flow');
113 *
114 * function createUrl (name) {
115 * return "http://test.com/" + name;
116 * }
117 *
118 * function curl (url) {
119 * return kit.request(url).then((body) => {
120 * kit.log('get');
121 * return body;
122 * });
123 * }
124 *
125 * function save (str) {
126 * kit.outputFile('a.txt', str).then(() => {
127 * kit.log('saved');
128 * });
129 * }
130 *
131 * var download = flow(createUrl, curl, save);
132 * // same as "download = flow([createUrl, curl, save])"
133 *
134 * download('home');
135 * ```
136 * @example
137 * Walk through first link of each page.
138 * ```js
139 * var kit = require('nokit');
140 * var flow = require('yaku/lib/flow');
141 *
142 * var list = [];
143 * function iter (url) {
144 * return {
145 * done: !url,
146 * value: url && kit.request(url).then((body) => {
147 * list.push(body);
148 * var m = body.match(/href="(.+?)"/);
149 * if (m) return m[0];
150 * });
151 * };
152 * }
153 *
154 * var walker = flow(iter);
155 * walker('test.com');
156 * ```
157 */
158 flow: require("./flow"),
159
160 /**
161 * Enable a helper to catch specific error type.
162 * It will be directly attach to the prototype of the promise.
163 * @param {class} type
164 * @param {Function} onRejected
165 * @return {Promise}
166 * ```js
167 * var Promise = require('yaku');
168 * require('yaku/lib/guard');
169 *
170 * class AnError extends Error {
171 * }
172 *
173 * Promise.reject(new AnError('hey'))
174 * .guard(AnError, (err) => {
175 * // only log AnError type
176 * console.log(err);
177 * })
178 * .then(() => {
179 * console.log('done');
180 * })
181 * .guard(Error, (err) => {
182 * // log all error type
183 * console.log(err)
184 * });
185 * ```
186 */
187 guard: require("./guard"),
188
189 /**
190 * if-else helper
191 * @param {Promise} cond
192 * @param {Function} trueFn
193 * @param {Function} falseFn
194 * @return {Promise}
195 * @example
196 * ```js
197 * var Promise = require('yaku');
198 * var yutils = require('yaku/lib/utils');
199 *
200 * yutils.if(Promise.resolve(false), () => {
201 * // true
202 * }, () => {
203 * // false
204 * })
205 * ```
206 */
207 "if": require("./if"),
208
209 /**
210 * **deprecate** Check if an object is a promise-like object.
211 * Don't use it to coercive a value to Promise, instead use `Promise.resolve`.
212 * @param {Any} obj
213 * @return {Boolean}
214 */
215 isPromise: require("./isPromise"),
216
217 /**
218 * Create a promise that never ends.
219 * @return {Promise} A promise that will end the current pipeline.
220 */
221 never: require("./never"),
222
223 /**
224 * Convert a node callback style function to a function that returns
225 * promise when the last callback is not supplied.
226 * @param {Function} fn
227 * @param {Any} self The `this` to bind to the fn.
228 * @return {Function}
229 * @example
230 * ```js
231 * var promisify = require('yaku/lib/promisify');
232 * function foo (val, cb) {
233 * setTimeout(() => {
234 * cb(null, val + 1);
235 * });
236 * }
237 *
238 * var bar = promisify(foo);
239 *
240 * bar(0).then((val) => {
241 * console.log val // output => 1
242 * });
243 *
244 * // It also supports the callback style.
245 * bar(0, (err, val) => {
246 * console.log(val); // output => 1
247 * });
248 * ```
249 */
250 promisify: require("./promisify"),
251
252 /**
253 * Create a promise that will wait for a while before resolution.
254 * @param {Integer} time The unit is millisecond.
255 * @param {Any} val What the value this promise will resolve.
256 * @return {Promise}
257 * @example
258 * ```js
259 * var sleep = require('yaku/lib/sleep');
260 * sleep(1000).then(() => console.log('after one second'));
261 * ```
262 */
263 sleep: require("./sleep"),
264
265 /**
266 * Read the `Observable` section.
267 * @type {Function}
268 */
269 Observable: require("./Observable"),
270
271 /**
272 * Retry a function until it resolves before a mount of times, or reject with all
273 * the error states.
274 * @version_added v0.7.10
275 * @param {Number | Function} countdown How many times to retry before rejection.
276 * @param {Number} span Optional. How long to wait before each retry in millisecond.
277 * When it's a function `(errs) => Boolean | Promise.resolve(Boolean)`,
278 * you can use it to create complex countdown logic,
279 * it can even return a promise to create async countdown logic.
280 * @param {Function} fn The function can return a promise or not.
281 * @param {Any} this Optional. The context to call the function.
282 * @return {Function} The wrapped function. The function will reject an array
283 * of reasons that throwed by each try.
284 * @example
285 * Retry 3 times before rejection, wait 1 second before each retry.
286 * ```js
287 * var retry = require('yaku/lib/retry');
288 * var { request } = require('nokit');
289 *
290 * retry(3, 1000, request)('http://test.com').then(
291 * (body) => console.log(body),
292 * (errs) => console.error(errs)
293 * );
294 * ```
295 * @example
296 * Here a more complex retry usage, it shows an random exponential backoff algorithm to
297 * wait and retry again, which means the 10th attempt may take 10 minutes to happen.
298 * ```js
299 * var retry = require('yaku/lib/retry');
300 * var sleep = require('yaku/lib/sleep');
301 * var { request } = require('nokit');
302 *
303 * function countdown (retries) {
304 * var attempt = 0;
305 * return async () => {
306 * var r = Math.random() * Math.pow(2, attempt) * 1000;
307 * var t = Math.min(r, 1000 * 60 * 10);
308 * await sleep(t);
309 * return attempt++ < retries;
310 * };
311 * }
312 *
313 * retry(countdown(10), request)('http://test.com').then(
314 * (body) => console.log(body),
315 * (errs) => console.error(errs)
316 * );
317 * ```
318 */
319 retry: require("./retry"),
320
321 /**
322 * Throw an error to break the program.
323 * @param {Any} err
324 * @example
325 * ```js
326 * var ythrow = require('yaku/lib/throw');
327 * Promise.resolve().then(() => {
328 * // This error won't be caught by promise.
329 * ythrow('break the program!');
330 * });
331 * ```
332 */
333 "throw": require("./throw"),
334
335 /**
336 * Create a promise that will reject after a while if the passed in promise
337 * doesn't settle first.
338 * @param {Promise} promise The passed promise to wait.
339 * @param {Integer} time The unit is millisecond.
340 * @param {Any} reason After time out, it will be the reject reason.
341 * @return {Promise}
342 * @example
343 * ```js
344 * var sleep = require('yaku/lib/sleep');
345 * var timeout = require('yaku/lib/timeout');
346 * timeout(sleep(500), 100)["catch"]((err) => {
347 * console.error(err);
348 * });
349 * ```
350 */
351 timeout: require("./timeout")
352};