李恒道 发表于 2023-2-7 16:02:53

mock.js改造兼容支持异步函数

下断点找一下,可以发现调用我们自己的mock函数处于
```js
      if (this.custom.async) setTimeout(done, this.custom.timeout) // 异步
                else done() // 同步

                function done() {
                    that.readyState = MockXMLHttpRequest.HEADERS_RECEIVED
                    that.dispatchEvent(new Event('readystatechange' /*, false, false, that*/ ))
                    that.readyState = MockXMLHttpRequest.LOADING
                    that.dispatchEvent(new Event('readystatechange' /*, false, false, that*/ ))

                    that.status = 200
                    that.statusText = HTTP_STATUS_CODES

                    // fix #92 #93 by @qddegtya
                    that.response = that.responseText = JSON.stringify(
                      convert(that.custom.template, that.custom.options),
                      null, 4
                    )

                    that.readyState = MockXMLHttpRequest.DONE
                    that.dispatchEvent(new Event('readystatechange' /*, false, false, that*/ ))
                    that.dispatchEvent(new Event('load' /*, false, false, that*/ ));
                    that.dispatchEvent(new Event('loadend' /*, false, false, that*/ ));
                }
```
可以发现是定时或者非定时然后执行done,done内部执行convert执行到我们的函数
```js
        // 数据模板 => 响应数据
        function convert(item, options) {
          return Util.isFunction(item.template) ?
                item.template(options) : MockXMLHttpRequest.Mock.mock(item.template)
        }

```
然而不支持async函数,很麻烦...只是同步的伪造数据还好
如果根据提交参数做异步的获取并且再返回就会不兼容直接变成undefined
因为done解耦做的还挺好的,所以可以直接改done
首先把done改成async
判断结果是否是promise,如果是promise就阻塞一下再继续调用
![图片.png](data/attachment/forum/202302/07/160653fususs70mmr6muv4.png)
然后我们可以改一下convert
因为async函数得到的是asyncfunction,而原来的是直接判断function是否是’function‘字符串
所以我们可以修改一下
![图片.png](data/attachment/forum/202302/07/160748ox8xmjzaxz74xkux.png)
目前测试是通的
![图片.png](data/attachment/forum/202302/07/160805qba8dinc9wy4wz14.png)
# 修改的函数代码
```js
            if (this.custom.async)
            setTimeout(() => {
                done();
            }, this.custom.timeout);
            // 异步
            else done(); // 同步
            async function done() {
            that.readyState = MockXMLHttpRequest.HEADERS_RECEIVED;
            that.dispatchEvent(
                new Event('readystatechange' /*, false, false, that*/)
            );
            that.readyState = MockXMLHttpRequest.LOADING;
            that.dispatchEvent(
                new Event('readystatechange' /*, false, false, that*/)
            );

            that.status = 200;
            that.statusText = HTTP_STATUS_CODES;
            const likePromise = convert(
                that.custom.template,
                that.custom.options
            );
            let result = likePromise;
            if (likePromise.then !== undefined) {
                result = await likePromise;
            }
            // fix #92 #93 by @qddegtya
            that.response = that.responseText = JSON.stringify(
                result,
                null,
                4
            );

            that.readyState = MockXMLHttpRequest.DONE;
            that.dispatchEvent(
                new Event('readystatechange' /*, false, false, that*/)
            );
            that.dispatchEvent(new Event('load' /*, false, false, that*/));
            that.dispatchEvent(new Event('loadend' /*, false, false, that*/));
            }
```
修改convert函数
```js
      // 数据模板 => 响应数据
      function convert(item, options) {
          return Util.type(item.template) === 'function' ||
            Util.type(item.template) === 'asyncfunction'
            ? item.template(options)
            : MockXMLHttpRequest.Mock.mock(item.template);
      }

```


```
页: [1]
查看完整版本: mock.js改造兼容支持异步函数