Blame view

node_modules/async/wrapSync.js 3.42 KB
aaac7fed   liuqimichale   add
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
  'use strict';
  
  Object.defineProperty(exports, "__esModule", {
      value: true
  });
  exports.default = asyncify;
  
  var _isObject = require('lodash/isObject');
  
  var _isObject2 = _interopRequireDefault(_isObject);
  
  var _initialParams = require('./internal/initialParams');
  
  var _initialParams2 = _interopRequireDefault(_initialParams);
  
  var _setImmediate = require('./internal/setImmediate');
  
  var _setImmediate2 = _interopRequireDefault(_setImmediate);
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  /**
   * Take a sync function and make it async, passing its return value to a
   * callback. This is useful for plugging sync functions into a waterfall,
   * series, or other async functions. Any arguments passed to the generated
   * function will be passed to the wrapped function (except for the final
   * callback argument). Errors thrown will be passed to the callback.
   *
   * If the function passed to `asyncify` returns a Promise, that promises's
   * resolved/rejected state will be used to call the callback, rather than simply
   * the synchronous return value.
   *
   * This also means you can asyncify ES2017 `async` functions.
   *
   * @name asyncify
   * @static
   * @memberOf module:Utils
   * @method
   * @alias wrapSync
   * @category Util
   * @param {Function} func - The synchronous function, or Promise-returning
   * function to convert to an {@link AsyncFunction}.
   * @returns {AsyncFunction} An asynchronous wrapper of the `func`. To be
   * invoked with `(args..., callback)`.
   * @example
   *
   * // passing a regular synchronous function
   * async.waterfall([
   *     async.apply(fs.readFile, filename, "utf8"),
   *     async.asyncify(JSON.parse),
   *     function (data, next) {
   *         // data is the result of parsing the text.
   *         // If there was a parsing error, it would have been caught.
   *     }
   * ], callback);
   *
   * // passing a function returning a promise
   * async.waterfall([
   *     async.apply(fs.readFile, filename, "utf8"),
   *     async.asyncify(function (contents) {
   *         return db.model.create(contents);
   *     }),
   *     function (model, next) {
   *         // `model` is the instantiated model object.
   *         // If there was an error, this function would be skipped.
   *     }
   * ], callback);
   *
   * // es2017 example, though `asyncify` is not needed if your JS environment
   * // supports async functions out of the box
   * var q = async.queue(async.asyncify(async function(file) {
   *     var intermediateStep = await processFile(file);
   *     return await somePromise(intermediateStep)
   * }));
   *
   * q.push(files);
   */
  function asyncify(func) {
      return (0, _initialParams2.default)(function (args, callback) {
          var result;
          try {
              result = func.apply(this, args);
          } catch (e) {
              return callback(e);
          }
          // if result is Promise object
          if ((0, _isObject2.default)(result) && typeof result.then === 'function') {
              result.then(function (value) {
                  invokeCallback(callback, null, value);
              }, function (err) {
                  invokeCallback(callback, err.message ? err : new Error(err));
              });
          } else {
              callback(null, result);
          }
      });
  }
  
  function invokeCallback(callback, error, value) {
      try {
          callback(error, value);
      } catch (e) {
          (0, _setImmediate2.default)(rethrow, e);
      }
  }
  
  function rethrow(error) {
      throw error;
  }
  module.exports = exports['default'];