如何将承诺 resolve() 转移到另一个承诺
How can I transfer a promise resolve() to another promise
假设我有一个 "JsonEditor" 模块(仅作为示例),它具有 3 个函数:get()、setProperty() 和 save()。
代码如下(问题如下):
var fs = require('fs')
, q = require('q');
var jsonEditorModule = (function() {
return {
get: function(jsonPath) {
// ...
},
save: function(jsonObject, jsonPath) {
var qJson = q.defer();
var jsonContent = JSON.stringify(jsonObject, null, 2);
fs.writeFile(jsonPath, jsonContent, function(err) {
if(err) {
qJson.reject(err);
}
else {
qJson.resolve();
}
});
return qJson.promise;
},
setProperty: function(prop, value, jsonPath) {
var self = this;
var qJson = q.defer();
this.get(jsonPath)
.then(
function(jsonObject) {
// Set the property
jsonObject[prop] = value;
// Save the file
self.save(jsonObject, jsonPath)
.then(
function() {
qJson.resolve();
},
function() {
qJson.reject();
},
);
}
);
return qJson.promise;
},
};
})();
module.exports = jsonEditorModule;
看到 setProperty() 函数中 save() 之后的 then() 了吗?
看起来很蠢吧?
我需要手动 resolve() 和 reject() 我的承诺吗?
我不能将 save() 行为转移到我的 setProperty() 承诺中吗?
希望问题够清楚(不要太蠢)。
谢谢
这里描述了你想要实现的目标:chaining,基本上,如果处理程序 returns 是一个承诺(我们称之为 innerPromiseFromHandler
),那么 [=13= 的处理程序] 在 innerPromiseFromHandler
获得分辨率值时将执行先前承诺中定义的:
var jsonEditorModule = (function() {
return {
get: function(jsonPath) {
return Q.delay(1000).then(function () {
document.write('get...<br/>');
return 'get';
});
},
save: function(result) {
return Q.delay(1000).then(function () {
document.write('save...<br/>');
return result + ' save';
});
},
setProperty: function(prop, value, jsonPath) {
return this.get(jsonPath)
.then(function(result) {
return jsonEditorModule.save(result);
});
}
};
})();
jsonEditorModule
.setProperty()
.then(function (result) {
document.write(result + ' finish');
})
<script src="http://cdnjs.cloudflare.com/ajax/libs/q.js/0.9.2/q.js"></script>
It looks stupid, right? Do I need to manually resolve()
and reject()
my promise?
是的,事实上这有一个自己的名字:手动 resolving/rejecting 一个额外的承诺被称为愚蠢 deferred antipattern。
Can't I just transfer the save()
behavior to my setProperty()
promise?
是的,这是微不足道的可能 - 它内置于 then
方法中:调用 .then()
returns 一个新的 return
回调值的承诺,即使该价值隐藏在承诺中。
var jsonEditorModule = {
get: function(jsonPath) {
// ...
},
save: function(jsonObject, jsonPath) {
return Q.ninvoke(fs, "writeFile", jsonPath, JSON.stringify(jsonObject, null, 2));
},
setProperty: function(prop, value, jsonPath) {
return this.get(jsonPath).then(function(jsonObject) {
// ^^^^^^
// Set the property
jsonObject[prop] = value;
// Save the file
return this.save(jsonObject, jsonPath);
// ^^^^^^
}.bind(this));
}
};
假设我有一个 "JsonEditor" 模块(仅作为示例),它具有 3 个函数:get()、setProperty() 和 save()。
代码如下(问题如下):
var fs = require('fs')
, q = require('q');
var jsonEditorModule = (function() {
return {
get: function(jsonPath) {
// ...
},
save: function(jsonObject, jsonPath) {
var qJson = q.defer();
var jsonContent = JSON.stringify(jsonObject, null, 2);
fs.writeFile(jsonPath, jsonContent, function(err) {
if(err) {
qJson.reject(err);
}
else {
qJson.resolve();
}
});
return qJson.promise;
},
setProperty: function(prop, value, jsonPath) {
var self = this;
var qJson = q.defer();
this.get(jsonPath)
.then(
function(jsonObject) {
// Set the property
jsonObject[prop] = value;
// Save the file
self.save(jsonObject, jsonPath)
.then(
function() {
qJson.resolve();
},
function() {
qJson.reject();
},
);
}
);
return qJson.promise;
},
};
})();
module.exports = jsonEditorModule;
看到 setProperty() 函数中 save() 之后的 then() 了吗?
看起来很蠢吧?
我需要手动 resolve() 和 reject() 我的承诺吗? 我不能将 save() 行为转移到我的 setProperty() 承诺中吗?
希望问题够清楚(不要太蠢)。
谢谢
这里描述了你想要实现的目标:chaining,基本上,如果处理程序 returns 是一个承诺(我们称之为 innerPromiseFromHandler
),那么 [=13= 的处理程序] 在 innerPromiseFromHandler
获得分辨率值时将执行先前承诺中定义的:
var jsonEditorModule = (function() {
return {
get: function(jsonPath) {
return Q.delay(1000).then(function () {
document.write('get...<br/>');
return 'get';
});
},
save: function(result) {
return Q.delay(1000).then(function () {
document.write('save...<br/>');
return result + ' save';
});
},
setProperty: function(prop, value, jsonPath) {
return this.get(jsonPath)
.then(function(result) {
return jsonEditorModule.save(result);
});
}
};
})();
jsonEditorModule
.setProperty()
.then(function (result) {
document.write(result + ' finish');
})
<script src="http://cdnjs.cloudflare.com/ajax/libs/q.js/0.9.2/q.js"></script>
It looks stupid, right? Do I need to manually
resolve()
andreject()
my promise?
是的,事实上这有一个自己的名字:手动 resolving/rejecting 一个额外的承诺被称为愚蠢 deferred antipattern。
Can't I just transfer the
save()
behavior to mysetProperty()
promise?
是的,这是微不足道的可能 - 它内置于 then
方法中:调用 .then()
returns 一个新的 return
回调值的承诺,即使该价值隐藏在承诺中。
var jsonEditorModule = {
get: function(jsonPath) {
// ...
},
save: function(jsonObject, jsonPath) {
return Q.ninvoke(fs, "writeFile", jsonPath, JSON.stringify(jsonObject, null, 2));
},
setProperty: function(prop, value, jsonPath) {
return this.get(jsonPath).then(function(jsonObject) {
// ^^^^^^
// Set the property
jsonObject[prop] = value;
// Save the file
return this.save(jsonObject, jsonPath);
// ^^^^^^
}.bind(this));
}
};