Defining the promise type
发布于 9 年前 作者 CommanderXL 4235 次浏览 最后一次编辑是 8 年前 来自 问答

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 容易理解得多的。

这个示例中:

  1. Promise 被调用后会产生一个闭包,里面存着 callback 这个变量,以及生成的 then 方法(负责处理完成后的结果)和 resolve 函数(负责通知任务完成)。所以 then 和 resolve(这个替代原来的 callback 作用,不同的是它要保证 then 要在先行执行,否则 callback 是空值) 都能访问 callback 变量。
  2. 调用传入的函数 fn,把 resolve 函数传给它。fn 是负责实际工作的,它必须在完成工作后调用接收到的 resolve 函数并告知它处理的结果是怎么样。
  3. then 很简单,它只是把 callback 存起来。
  4. resolve 函数被调用后,它要负责调用 then 存起来的 callback。示例中 setTimeout 的意思就是要确保 then 被调用后再执行 callback。把它换成 nextTick 也是一样的。
  5. 关键还是 setTimeout ,因为 doSomething 里面是同步代码,如果 resolve 时不 setTimeout/nextTick , callback 会早于 then 被调用,这样就会出错。

@klesh

	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应该是对等的?

不是,这个是 resolve 后被调用的 callback。这些都是些基本概念,讲起来太长,建议找些介绍 javascript 的文章研究一下,特别是介绍函数式编程和闭包之类的文章,另外手动写代码去验证自己的理解很重要。另外可以看下《深入浅出NODE.JS》,多看 上面有电子版卖,几十块钱很值。

回到顶部