Node.js 如何用新的Promise()替换Promise.defer
所以我看到,Node.js 如何用新的Promise()替换Promise.defer,node.js,promise,Node.js,Promise,所以我看到,Promise.defer现在已经被弃用了,我们现在应该使用newpromise。我不知道如何在这个例子中做到这一点 var Promise = require('bluebird'); var interval; var rollDice = function (resolver) { console.log("rolling"); if (Math.floor(Math.random() * 10) == 7) { clearInterval(interval)
Promise.defer
现在已经被弃用了,我们现在应该使用newpromise
。我不知道如何在这个例子中做到这一点
var Promise = require('bluebird');
var interval;
var rollDice = function (resolver) {
console.log("rolling");
if (Math.floor(Math.random() * 10) == 7) {
clearInterval(interval);
resolver.resolve();
}
}
var rollTill7 = function (ms) {
var resolver = Promise.defer();
interval = setInterval(function(){rollDice(resolver);},ms);
return resolver.promise;
}
rollTill7(100).then(function(){
console.log("rolled a 7");
});
一般来说,建议远离旧的延迟模型,因为您希望承诺的创建者负责解决或拒绝它-这只会使控制流更容易遵循。您不希望将解决或拒绝的责任转交给其他代码 如果解决或拒绝的决策涉及外部代码(例如
rollDice()
函数),则它可以返回用于解决或拒绝的信息。例如,在您的代码示例中,可以这样做
请注意,rollDice()
函数现在只是一个骰子滚动函数,它告诉您是否滚动了特定数量的骰子。然后,另一个函数使用它来确定控制流,而不是将控制流放入骰子滚动函数本身
var rollDice = function() {
console.log("rolling");
return Math.floor(Math.random() * 10) + 1;
}
var rollTillNum = function(num, ms) {
return new Promise(function(resolve) {
var interval = setInterval(function(){
if (rollDice() === num) {
resolve();
clearInterval(interval);
}
}, ms);
});
}
rollTillNum(7, 100).then(function(){
console.log("rolled a 7");
});
更改摘要:
interval
变量现在包含在本地范围内rollDice()
函数现在是通用函数,因此可以在其他上下文中使用rollDice()
现在返回基于1的值,而不是基于0的值(因为骰子就是这样工作的)rollTillNum()
虽然上述解决方案更通用(使用外部函数提供是否应解决问题的反馈),但在这种特定情况下,如果您甚至不需要外部可用的
rollDice()
函数,则可以将其完全包含在rollTillNum()
函数中:
var rollTillNum = function(num, ms) {
return new Promise(function(resolve) {
var interval = setInterval(function(){
if ((Math.floor(Math.random() * 10) + 1) === num) {
resolve();
clearInterval(interval);
}
}, ms);
});
}
rollTillNum(7, 100).then(function(){
console.log("rolled a 7");
});
以下是制作成工作演示的上述代码:
document.getElementById(“roll”).addEventListener(“单击”,函数(){
var start=Date.now();
rollTillNum(7100)。然后(函数(cnt){
var经过=((Date.now()-start)/1000).toFixed(1);
日志(“需要“+经过+”秒和“+cnt+”转鼓才能转鼓7”);
});
});
var rollDice=函数(){
控制台。日志(“滚动”);
返回Math.floor(Math.random()*10)+1;
}
var rollTillNum=函数(num,ms){
返回新承诺(函数(解析){
var-cntr=0;
var interval=setInterval(函数(){
++碳纳米管;
if(rollDice()==num){
解决(cntr);
间隔时间;
}
},ms);
});
}
函数日志(x){
var div=document.createElement(“div”);
div.innerHTML=x;
文件.正文.附件(div);
}
滚7
试试这个
var rollDice = function (resolve) {
console.log("rolling");
if (Math.floor(Math.random() * 10) == 7) {
clearInterval(interval);
resolve();
}
}
var rollTill7 = function (ms) {
return new Promise(function(resolve) {
interval = setInterval(function() {
rollDice(resolve);
}, ms);
});
}
使用
newpromise(constructorFn)
的直接等效方法是在constructorFn
中写入interval=setInterval(…)
,并将constructorFn的resolve参数传递给rollDice()
,而不是原始的延迟对象
var Promise = require('bluebird');
var interval;
var rollDice = function (resolve) {
console.log("rolling");
if (Math.floor(Math.random() * 10) == 7) {
clearInterval(interval);
resolve();
}
};
var rollTill7 = function (ms) {
return new Promise(function(resolve, reject) {
interval = setInterval(function() {
rollDice(resolve);
}, ms);
});
};
rollTill7(100).then(function() {
console.log("rolled a 7");
});
如果interval
和rollDice()
也被移动到promise的构造函数中,那么解决方案会变得更加整洁。不仅从外部名称空间中删除了两个成员,而且还避免了传递resolve
的需要-由于关闭,rollDice()
可以访问它
var Promise = require('bluebird');
var rollTill7 = function (ms) {
return new Promise(function(resolve, reject) {
var interval;
var rollDice = function () {
console.log("rolling");
if (Math.floor(Math.random() * 10) == 7) {
clearInterval(interval);
resolve();
}
};
interval = setInterval(rollDice, ms);
});
};
rollTill7(100).then(function() {
console.log("rolled a 7");
});
更进一步,您可能会选择将
rollDice()
作为匿名函数移动到setInterval
表达式中。这将避免命名函数的问题,即它不只是“掷骰子”,它还可以解决问题。接受这一答案,因为我很欣赏改进的作用域解决方案。@GroovyDotCom-我不认为这两种解决方案都是理想的。第一种方法仍然将解决承诺的责任委托给外部函数,这是完全不必要的,并且会使理解和遵循代码的能力变得复杂,尤其是在更大的代码体中。首先,不使用延迟的方法的全部目的是将解决和拒绝责任保持在本地,而不是将其转移到其他地方。第二个示例很方便,但它隐藏了rollDice()
函数,因此无法使用elsewhere@GroovyDotCom-虽然在这个特定示例中隐藏rollDice()
函数可能没问题,但更一般的情况是,该函数在外部声明,因为它在其他地方使用(否则,它甚至不需要是一个函数)。您可以在这里看到其他答案之一,以获得更一般的解决方案。@jfriend00,我同意所有这些。为了演示“如何用新承诺替换承诺。延迟()”的原则,我决定尽可能地坚持OP的原始方法。实际上,我会按照你的建议做很多事情。谢谢Roamer。这是一个艰难的决定,但经过编辑,我认为Jfriend现在有了完整的答案。没有理由使用rollDice()
函数必须知道某个承诺的任何信息,因此没有理由将承诺的解析委托给承诺构造函数之外的人。rollDice()
生命中的任务是进行随机滚动。rollTill7()
中的代码可以使用rollDice()的返回值
然后rollTill7()
可以确定是否达到了所需的数量,以及是否应该解决承诺。如果承诺是在同一代码块中创建和解决的,则最容易理解。@jfriend00,你是对的。我只是替换