diff --git a/README.md b/README.md index 07063b4..eb0cfb1 100644 --- a/README.md +++ b/README.md @@ -1041,14 +1041,19 @@ progress decorator **Kind**: static property of [CPromise](#module_CPromise) -### CPromise~CPromise ⇐ Promise -CPromise class +### CPromise~CPromise : object +Creates a new CPromise instance -**Kind**: inner class of [CPromise](#module_CPromise) +**Kind**: inner namespace of [CPromise](#module_CPromise) **Extends**: Promise -* [~CPromise](#module_CPromise..CPromise) ⇐ Promise - * [new CPromise([executor], [options])](#new_module_CPromise..CPromise_new) +| Param | Type | Description | +| --- | --- | --- | +| [executor] | CPromiseExecutorFn | promise executor function that will be invoked in the context of the new CPromise instance | +| [options] | CPromiseOptions | | + + +* [~CPromise](#module_CPromise..CPromise) : object * _instance_ * [.signal](#module_CPromise..CPromise+signal) : AbortSignal * [.isPending](#module_CPromise..CPromise+isPending) ⇒ Boolean @@ -1092,7 +1097,7 @@ CPromise class * [.toString([entireChain])](#module_CPromise..CPromise+toString) ⇒ string * _static_ * [.isCanceledError(thing)](#module_CPromise..CPromise.isCanceledError) ⇒ boolean - * [.delay(ms, value)](#module_CPromise..CPromise.delay) ⇒ CPromise + * [.delay(ms, value, [options])](#module_CPromise..CPromise.delay) ⇒ CPromise * [.all(iterable, [options])](#module_CPromise..CPromise.all) ⇒ CPromise * [.race(thenables)](#module_CPromise..CPromise.race) ⇒ CPromise * [.allSettled(iterable, options)](#module_CPromise..CPromise.allSettled) ⇒ CPromise @@ -1101,17 +1106,6 @@ CPromise class * [.promisify(originalFn, [options])](#module_CPromise..CPromise.promisify) ⇒ function * [.run(generatorFn, [options])](#module_CPromise..CPromise.run) ⇒ CPromise - - -#### new CPromise([executor], [options]) -Creates a new CPromise instance - - -| Param | Type | Description | -| --- | --- | --- | -| [executor] | CPromiseExecutorFn | promise executor function that will be invoked in the context of the new CPromise instance | -| [options] | CPromiseOptions | | - #### cPromise.signal : AbortSignal @@ -1541,15 +1535,17 @@ Checks if thing is an CanceledError instance -#### CPromise.delay(ms, value) ⇒ CPromise +#### CPromise.delay(ms, value, [options]) ⇒ CPromise Returns a CPromise that will be resolved after specified timeout **Kind**: static method of [CPromise](#module_CPromise..CPromise) -| Param | Type | Description | -| --- | --- | --- | -| ms | Number | delay before resolve the promise with specified value | -| value | | | +| Param | Type | Default | Description | +| --- | --- | --- | --- | +| ms | Number | | delay before resolve the promise with specified value | +| value | | | | +| [options] | object | | | +| [options.progressTick] | number | 1000 | progress timer tick, must be >= 100ms | diff --git a/README2.md b/README2.md new file mode 100644 index 0000000..e69de29 diff --git a/lib/c-promise.js b/lib/c-promise.js index 8ec6794..a707013 100644 --- a/lib/c-promise.js +++ b/lib/c-promise.js @@ -1014,16 +1014,46 @@ class CPromise extends Promise { * Returns a CPromise that will be resolved after specified timeout * @param {Number} ms - delay before resolve the promise with specified value * @param value + * @param {object} [options] + * @param {number} [options.progressTick= 1000] progress timer tick, must be >= 100ms * @returns {CPromise} */ - static delay(ms, value) { + static delay(ms, value, options) { return new this((resolve, reject, scope) => { if (!Number.isFinite(ms)) { throw TypeError('timeout must be a finite number'); } + const timer = setTimeout(() => resolve(value), ms); scope.onCancel(() => clearTimeout(timer)); + + const {progressTick= 1000}= options!==undefined ? validateOptions(options, { + progressTick: numberFinitePositive + }) : {}; + + if (progressTick) { + if (progressTick < 100) { + throw Error('progressTick must be grater than 100ms to avoid performance impact'); + } + + const captureProgress= ()=>{ + if (ms > progressTick * 1.5) { + let timestamp = Date.now(); + const progressTimer = setInterval(() => { + scope.progress((Date.now() - timestamp) / ms); + }, progressTick); + + scope.on('done', () => clearTimeout(progressTimer)); + } + } + + if(scope.isCaptured){ + captureProgress(); + }else{ + scope.onCapture(captureProgress); + } + } }) } diff --git a/package-lock.json b/package-lock.json index 7fc656d..f5306e1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1125,9 +1125,9 @@ } }, "collect-all": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/collect-all/-/collect-all-1.0.3.tgz", - "integrity": "sha512-0y0rBgoX8IzIjBAUnO73SEtSb4Mhk3IoceWJq5zZSxb9mWORhWH8xLYo4EDSOE1jRBk1LhmfjqWFFt10h/+MEA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/collect-all/-/collect-all-1.0.4.tgz", + "integrity": "sha512-RKZhRwJtJEP5FWul+gkSMEnaK6H3AGPTTWOiRimCcs+rc/OmQE3Yhy1Q7A7KsdkG3ZXVdZq68Y6ONSdvkeEcKA==", "dev": true, "requires": { "stream-connect": "^1.0.2", @@ -1238,9 +1238,9 @@ "dev": true }, "common-sequence": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/common-sequence/-/common-sequence-2.0.0.tgz", - "integrity": "sha512-f0QqPLpRTgMQn/pQIynf+SdE73Lw5Q1jn4hjirHLgH/NJ71TiHjXusV16BmOyuK5rRQ1W2f++II+TFZbQOh4hA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/common-sequence/-/common-sequence-2.0.2.tgz", + "integrity": "sha512-jAg09gkdkrDO9EWTdXfv80WWH3yeZl5oT69fGfedBNS9pXUKYInVJ1bJ+/ht2+Moeei48TmSbQDYMc8EOx9G0g==", "dev": true }, "commondir": { @@ -1637,13 +1637,21 @@ "dev": true }, "file-set": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/file-set/-/file-set-4.0.1.tgz", - "integrity": "sha512-tRzX4kGPmxS2HDK2q2L4qcPopTl/gcyahve2/O8l8hHNJgJ7m+r/ZncCJ1MmFWEMp1yHxJGIU9gAcsWu5jPMpg==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/file-set/-/file-set-4.0.2.tgz", + "integrity": "sha512-fuxEgzk4L8waGXaAkd8cMr73Pm0FxOVkn8hztzUW7BAHhOGH90viQNXbiOsnecCWmfInqU6YmAMwxRMdKETceQ==", "dev": true, "requires": { - "array-back": "^4.0.1", + "array-back": "^5.0.0", "glob": "^7.1.6" + }, + "dependencies": { + "array-back": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-5.0.0.tgz", + "integrity": "sha512-kgVWwJReZWmVuWOQKEOohXKJX+nD02JAZ54D1RRWlv8L0NebauKAaFxACKzB74RTclt1+WNz5KHaLRDAPZbDEw==", + "dev": true + } } }, "fill-range": { @@ -2400,9 +2408,9 @@ "dev": true }, "jsdoc": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.5.tgz", - "integrity": "sha512-SbY+i9ONuxSK35cgVHaI8O9senTE4CDYAmGSDJ5l3+sfe62Ff4gy96osy6OW84t4K4A8iGnMrlRrsSItSNp3RQ==", + "version": "3.6.6", + "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.6.tgz", + "integrity": "sha512-znR99e1BHeyEkSvgDDpX0sTiTu+8aQyDl9DawrkOGZTTW8hv0deIFXx87114zJ7gRaDZKVQD/4tr1ifmJp9xhQ==", "dev": true, "requires": { "@babel/parser": "^7.9.4", @@ -2710,9 +2718,9 @@ "dev": true }, "marked": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/marked/-/marked-1.1.1.tgz", - "integrity": "sha512-mJzT8D2yPxoPh7h0UXkB+dBj4FykPJ2OIfxAWeIHrvoHDkFxukV/29QxoFQoPM6RLEwhIFdJpmKBlqVM3s2ZIw==", + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/marked/-/marked-1.2.9.tgz", + "integrity": "sha512-H8lIX2SvyitGX+TRdtS06m1jHMijKN/XjfH6Ooii9fvxMlh8QdqBfBDkGUpMWH2kQNrtixjzYUa3SH8ROTgRRw==", "dev": true }, "mdurl": { @@ -6616,9 +6624,9 @@ "dev": true }, "object-to-spawn-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/object-to-spawn-args/-/object-to-spawn-args-2.0.0.tgz", - "integrity": "sha512-ZMT4owlXg3JGegecLlAgAA/6BsdKHn63R3ayXcAa3zFkF7oUBHcSb0oxszeutYe0FO2c1lT5pwCuidLkC4Gx3g==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object-to-spawn-args/-/object-to-spawn-args-2.0.1.tgz", + "integrity": "sha512-6FuKFQ39cOID+BMZ3QaphcC8Y4cw6LXBLyIgPU+OhIYwviJamPAn+4mITapnSBQrejB+NNp+FMskhD8Cq+Ys3w==", "dev": true }, "object.assign": { @@ -7246,15 +7254,21 @@ "dev": true }, "sort-array": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/sort-array/-/sort-array-4.1.2.tgz", - "integrity": "sha512-G5IUpM+OcVnyaWHMv84Y/RQYiFQoSu6eUtJZu840iM6nR7zeY/eOGny2epkr5VKqCGDkOj3UBzOluDZ7hFpljA==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/sort-array/-/sort-array-4.1.4.tgz", + "integrity": "sha512-GVFN6Y1sHKrWaSYOJTk9093ZnrBMc9sP3nuhANU44S4xg3rE6W5Z5WyamuT8VpMBbssnetx5faKCua0LEmUnSw==", "dev": true, "requires": { - "array-back": "^4.0.1", + "array-back": "^5.0.0", "typical": "^6.0.1" }, "dependencies": { + "array-back": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-5.0.0.tgz", + "integrity": "sha512-kgVWwJReZWmVuWOQKEOohXKJX+nD02JAZ54D1RRWlv8L0NebauKAaFxACKzB74RTclt1+WNz5KHaLRDAPZbDEw==", + "dev": true + }, "typical": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/typical/-/typical-6.0.1.tgz", diff --git a/test/tests/CPromise.js b/test/tests/CPromise.js index 3dc5158..306e047 100644 --- a/test/tests/CPromise.js +++ b/test/tests/CPromise.js @@ -869,6 +869,7 @@ module.exports = { } }, }, + 'CPromise.retry': { 'should reject if all retries failed': async () => { let counter = 0; @@ -898,6 +899,30 @@ module.exports = { assert.strictEqual(value, 123); }) } - } + }, + 'CPromise.delay': { + 'progress capturing' : async()=>{ + let index= 0; + const time= 1800; + const tick= 500; + const calc= (index)=> (index * tick) / time; + const arr= [calc(1), calc(2), calc(3), 1]; + + return new Promise((resolve, reject)=>{ + CPromise.run(function*(){ + yield CPromise.delay(time, undefined, {progressTick: tick}); + }).progress(v=> { + try{ + assert.ok(Math.abs(v- arr[index])<0.1, `${v}!=${arr[index]} (${arr})`); + index++; + }catch(err){ + reject(err); + } + }).then(()=>{ + assert.strictEqual(index, 4); + }).then(resolve, reject); + }); + } + } };