123
function Promise(fn) {
var callback = null;
this.then = function(cb) {
callback = cb;
};
function resolve(value) {
setTimeout(function() {
callback(value);
}, 1);
}
fn(resolve);
}
function doSomething() {
return new Promise(function(resolve) {
var value = 42;
resolve(value);
});
}
doSomething().then(function(data){
console.log("got the data "+data);//输出"got the data 42"
})
这段代码感觉理解起来有点困难,特别是函数的传递和匿名函数的传值。不是很懂
5 回复
本质上它是这样的:
function asyncWork(callback) {
// 这是一个异步操作,无法直接返回值,所以你调用我的时候要给我一个 callback。我完成后调用它
setTimeout(function() { // 这个是模拟异步操作的,比如说 fs.read,数据库的 query 都是这样的调用形式。
callback(value); // 这个是一般形式的回调
});
}
以上的代码就是标准的规范写法,但这种写法,会有回调地狱的问题,所以 Promise 来了,采用链式操作避免回调地狱同时增加代码可读性。像 doSomething().then(…)这样的代码是要比使用 callback 容易理解得多的。
这个示例中:
- Promise 被调用后会产生一个闭包,里面存着 callback 这个变量,以及生成的 then 方法(负责处理完成后的结果)和 resolve 函数(负责通知任务完成)。所以 then 和 resolve(这个替代原来的 callback 作用,不同的是它要保证 then 要在先行执行,否则 callback 是空值) 都能访问 callback 变量。
- 调用传入的函数 fn,把 resolve 函数传给它。fn 是负责实际工作的,它必须在完成工作后调用接收到的 resolve 函数并告知它处理的结果是怎么样。
- then 很简单,它只是把 callback 存起来。
- resolve 函数被调用后,它要负责调用 then 存起来的 callback。示例中 setTimeout 的意思就是要确保 then 被调用后再执行 callback。把它换成 nextTick 也是一样的。
- 关键还是 setTimeout ,因为 doSomething 里面是同步代码,如果 resolve 时不 setTimeout/nextTick , callback 会早于 then 被调用,这样就会出错。
this.then=function(cb){
callback=cb;
}
这个地方传的形参cb能不能理解成传入then( )
里面的函数或者对象?
function Promise(fn){
......
fn(resolve); //这里地方该怎么理解呢?是不是在创建Promise对象的时候就要调用resolve( )函数,
}
function doSomething(){
return new Promise(function(resolve){
var value=42;
resolve(value); //这里传递的resolve函数和在Promise构造函数里面定义的resolve函数有什么关系?
})
}
这里, fn = doSomething 在 Promise 里 resolve 没有被调用,它被创建后传给了 doSomething 。没有括号就只是传值,而不是调用。函数的创建和调用是两个概念。 在 doSomething 里,那个 resolve 就是 Promise 里面创建后,传给 fn 的 resolve。
@klesh 在then( )里面传递的函数的
then(function(data){
console.log("got the data "+data);
})
是不是和在Promise里传递的resolve应该是对等的?