react-isomorphic-boilerplate icon indicating copy to clipboard operation
react-isomorphic-boilerplate copied to clipboard

server/middlewares/clientRoute.js中路由匹配match()函数问题前是否要加await操作符?

Open sivkun opened this issue 7 years ago • 9 comments

match({routes,location:ctx.url},(error,redirectLocation,renderProps)=>{ _renderProps=renderProps }) 改为: await match({routes,location:ctx.url},(error,redirectLocation,renderProps)=>{ _renderProps=renderProps }) 我使用你个这脚手架,学习开发一个小项目,运行npm run dev ,浏览器可以正常访问。 但是构建后,执行npm start,页面提示Not found! 经过调试发现,在match函数回调中为_renderProps赋值。在match返回前继续往下运行,提示not found。 奇怪的是开发模式下正常,这是为什么呢?

sivkun avatar Mar 09 '17 12:03 sivkun

await关键字后面跟的只能是一个Promise对象

chikara-chan avatar Mar 09 '17 12:03 chikara-chan

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/await,如果这个值不是一个 promise,那么会把它转换成一个已经 resolved 的 promise,并且等待它。这里match确实是异步的,_renderProps在回调中被赋值,在赋值前,程序如果继续往下执行,会出问题啊。这个项目,没有出现问题,但是我用这个框架做一个demo时,确实出了问题。

sivkun avatar Mar 09 '17 12:03 sivkun

match本身是一个同步方法,不涉及网络请求与文件操作,可以在代码match函数内外console.log查看执行顺序

chikara-chan avatar Mar 09 '17 13:03 chikara-chan

方便上传项目源码吗

chikara-chan avatar Mar 09 '17 13:03 chikara-chan

我就是用console.log发现的这个问题。很奇怪的是,在dev模式没有这个问题。源码在这https://github.com/sivkun/myplayer-isomorphic。

sivkun avatar Mar 09 '17 13:03 sivkun

https://github.com/ReactTraining/react-router/issues/4677 产生原因:webpack2与webpack1对require.ensure的打包机制处理方式不同

chikara-chan avatar Mar 19 '17 07:03 chikara-chan

谢谢,我看一下

sivkun avatar Mar 19 '17 10:03 sivkun

审查webpack打包后的代码,可以看到 webpack1中require.ensure原型是

/******/ 	__webpack_require__.e = function requireEnsure(chunkId, callback) {
/******/ 		// "1" is the signal for "already loaded"
/******/ 		if(!installedChunks[chunkId]) {
/******/ 			var chunk = require("./chunk." + ({"1":"home","2":"explore","3":"about"}[chunkId]||chunkId) + ".js");
/******/ 			var moreModules = chunk.modules, chunkIds = chunk.ids;
/******/ 			for(var moduleId in moreModules) {
/******/ 				var _m = moreModules[moduleId];

/******/ 				// Check if module is deduplicated
/******/ 				switch(typeof _m) {
/******/ 				case "object":
/******/ 					// Module can be created from a template
/******/ 					modules[moduleId] = (function(_m) {
/******/ 						var args = _m.slice(1), templateId = _m[0];
/******/ 						return function (a,b,c) {
/******/ 							modules[templateId].apply(this, [a,b,c].concat(args));
/******/ 						};
/******/ 					}(_m));
/******/ 					break;
/******/ 				case "function":
/******/ 					// Normal module
/******/ 					modules[moduleId] = _m;
/******/ 					break;
/******/ 				default:
/******/ 					// Module is a copy of another module
/******/ 					modules[moduleId] = modules[_m];
/******/ 					break;
/******/ 				}
/******/ 			}
/******/ 			for(var i = 0; i < chunkIds.length; i++)
/******/ 				installedChunks[chunkIds[i]] = 1;
/******/ 		}
/******/ 		callback.call(null, __webpack_require__);
/******/ 	};

webpack2的require.ensure原型是

/******/ 	__webpack_require__.e = function requireEnsure(chunkId) {
/******/ 		// "0" is the signal for "already loaded"
/******/ 		if(installedChunks[chunkId] !== 0) {
/******/ 			var chunk = require("./" + chunkId + ".bundle.js");
/******/ 			var moreModules = chunk.modules, chunkIds = chunk.ids;
/******/ 			for(var moduleId in moreModules) {
/******/ 				modules[moduleId] = moreModules[moduleId];
/******/ 			}
/******/ 			for(var i = 0; i < chunkIds.length; i++)
/******/ 				installedChunks[chunkIds[i]] = 0;
/******/ 		}
/******/ 		return Promise.resolve();
/******/ 	};

webpack1直接调用回调函数,webpack2返回的是个promise

chikara-chan avatar Mar 20 '17 07:03 chikara-chan

我也遇到了上面的问题,但我改为一下: if(typeof require.ensure !=='function'){ require.ensure = function(dependencies,callback){ setTimeout(function() { callback(require) });
} }

还是无法解决,match的回调还是后执行,不知道有没有其他方法呢~谢谢

kevin-love avatar Jul 19 '17 08:07 kevin-love