co是一个基于ES6 Generator特性实现的【异步流程同步化】写法的工具库。
co需要使用Promise特性,所以,我们先来创建一个使用Promise来处理的异步方法:
function myAsyncFunc() {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log("myAsyncFunction done!");
resolve({
data: "Hello,World"
})
}, 2000);
});
}
然后,直接使用这个方法的话,就会如下,使用了then/catch的回调方式来处理调用结果和异常处理:
myAsyncFunc().then(function (result) {
console.log(result.data); //Hello,World
}).catch(function (err) {
//...
});
而如果是使用co的话,则会像这样:
co(function *() {
try {
var result = yield myAsyncFunc();
console.log(result.data); //Hello,World
} catch(e) {
}
});
这样的写法,是不是就是我们非常熟悉的,比较符合逻辑思维习惯的同步写法了?
关于co的用法,在本文中我就不多展开了,有兴趣的朋友可以自行搜索相关资料。我今天要讲的是,如何在小程序环境下面成功的使用co。
1. 开启语言转译选项
由于要使用到ES6的generator,而又要为了兼容性,我们必须对ES6的语法进行降级转译,变成ES5。
开启语言转译选项2. 引入generator支撑库
经过转译后的代码,需要依赖一个regeneratorRuntime,才能支持generator特性。Facebook开源的一个regenerator就是这样一个库,Github地址:https://github.com/facebook/regenerator/
你可以通过npm来下载这个regenerator库:
npm install regenerator
然后将下载文件中名为regenerator-runtime.js的文件拿出来,放到我们的小程序代码中去。
3.下载co和Promise库
接着,通过npm下载co库:
npm install co
将下载文件中名为co.js文件拿出来,放到我们的小程序代码中去。
因为需要依赖Promise,所以我们需要引入一个Promise实现库。在此我们选用一个小而兼容性好的库es6-promise。同样可以通过npm下载:
npm install es6-promise
将es6-promise.js放到我们的小程序代码中。
4.引入小程序代码中
使用前,将这些库正确的引入我们的代码:
const Promise = global.Promise = require('../../libs/es6-promise')
const regeneratorRuntime = global.regeneratorRuntime = require('../../libs/regenerator-runtime')
const co = require('../../libs/co')
好了,接下来就可以开始愉快的使用co进行编程了。
网友评论
// 下滑加载更多
lower: function(e){
// 为什么是*12?
if(this.data.loadState || (this.data.options.pageNo)*10 >= this.data.courseListTotal) return;
this.data.options.pageNo++;
this.loadSearchData(function(data){
this.data.loadState = false;
this.setData({
"courseList": this.data.courseList.concat(data.courseList)
})
}.bind(this));
}
在请求接口时把flag改成true,在请求success后改成false么,现在换成yield之后是像我现在这样写可以吗?
app.co(function* (){
try{
console.log(that.data.tagId)
that.data.loadState = true
var params = {
tagId: that.data.tagId,
pageNo: that.data.pageNo,
}
var result = yield app.getApi('get', 'https://yoururl', params)
that.data.loadState = false
console.log(1, result)
that.setData({
excellentcourse: that.data.excellentcourse.concat(result.data.courseList),
courseListTotal: result.data.total
})
} catch(e) {
}
})
,对yield还是没有深入理解呀。。是不是不需要这样控制了,因为代码现在是同步执行了
getApi里是这样的
function getApi(method, url, params={}, ){
method = method.toUpperCase()
var methodHeader = {}
if(method == "POST"){
methodHeader = { "content-type": "application/x-www-form-urlencoded" }
} else if (method == "GET") {
methodHeader = { 'content-type': 'application/json' }
}
return new Promise((resolve, reject) => {
wx.request({
url: url,
method: 'GET',
header: methodHeader,
data: params,
success: function (json) {
resolve(json)
},
fail: function (json) {
reject(json)
}
})
})
}
module.exports = getApi
不写在success里面我不会了~~
if (that.data.loadState) return; //loading中,忽略重复调用
regenerator-runtime比较迷茫,文件夹有两个,regenerator和regenerator-runtime。且里面的文件各有一个runtime.js和runtime-module.js。原谅我前端技术还不到看懂源码的程度,不知道该怎么引,求助