function test() {
let m = { a: 1, b: 2 };
let n = {};
return new Promise(function (resolve) {
for (let key in m) {
n[key] = m[key];
resolve(n)
}
})
}
test().then(function (r) {
console.log(r);
})
输出结果:
{ a: 1, b: 2 }
求解,为何输出不是{a: 1}
?
let
和const
是 ES6 标准中两个新的用于声明变量的语法。for (let key in m)
在 ES5 中可被写为for (var key in m)
,两者之间的区别只是let
和var
声明的变量作用域不一样。详细信息可看这里:http://es6.ruanyifeng.com/#docs/let
@leizongmin 还有个问题我不太明白,resolve何时执行?
这是因为: resolve 不能打断 for 循环,当第一次 for 循环里 resolve 了 n,由于 Promise 是异步的,这里没有立即调用 then,会先执行完当前的函数再异步调用 then 的,所以这里会继续执行 for 语句给 n 添加属性。
而当第二次调用 resolve 时,由于 Promise 的规定,resolve 和 reject 两只能调用一次,多次调用只取第一次调用的结果,所有这里第二次调用可以当成无效的。
promise这么用不行,楼主这个需求可以用generator + co (或bluebird的coroutine),也可以用async await
为啥要这样用? 自豪地采用 CNodeJS ionic
因为 promise是异步的,需要在resolve后的下一个tick 才能执行then,除非你加break;或者settimeout,否则for就会执行完成。而你的参数是一个对象,实际是指针,所以结果如你所见的。
试一下这个你就知道了。
function test() {
let m = { a: 1, b: 2 ,c:3};
let n = {};
return new Promise(function (resolve) {
for (let key in m) {
if(key!='a'){
setTimeout(function(){
n[key] = m[key];
console.log('before resolve',key,Date.now())
},0);
}
else n[key] = m[key];
resolve(n);
}
})
}
test().then(function (r) {
console.log(r,Date.now());
})
使用es6新特性let或者匿名函数自执行就可以了
for (let key in m) {
n[key] = m[key];
return resolve(n)
}
在resolve前加return就可以立即返回,否则会继续执行循环体
你可以去看promise的规范,你可以resolve n次,但是会以第一次的resolve为准,你上面的写法相当于resolve一个引用n次,每次动态改变引用所代表的对象。最后取resolve的第一次的引用,当然是你写的那种了
因为 n 是引用