javascript ES6 动态链接承诺
javascript ES6 dynamically chaining promises
我正在尝试动态链接承诺,以便处理需要按顺序发生的未知数量的异步调用。我正在使用原生支持 Promise 的 IO.JS/chrome。
promise 的创建会立即触发(至少相对于控制台输出而言)。我期待能够收集承诺然后传递给 Promise.all,但到那时他们已经因为我不明白的原因被解雇了。
下面是一种链接方法,由
上的评论建议
var lastPr = null;
console.log(" exit setup......................");
while(this.statesToExit.length > 0) {
var v = this.statesToExit.shift();
console.log("new Promise...");
var pr = new Promise(function (resolve, reject) {
console.log("doing Exit stuff at time " +curTime);
resolve(); //SOMETHING MORE SUBSTANTIAL GOES HERE
});
console.log("lastPr.then.");
if (lastPr != null) {
lastPr.then(pr);
}
lastPr = pr;
// console.log("adding pr to worklist");
// promiseList.push(pr);
// });
}
另一种方法是
var promiseList= [];
console.log(" exit setup......................");
while(this.statesToExit.length > 0) {
var v = this.statesToExit.shift();
console.log("new Promise...");
var pr = new Promise(function (resolve, reject) {
console.log("doing Exit stuff at time " +curTime);
resolve(); //SOMETHING MORE SUBSTANTIAL GOES HERE
});
console.log("adding pr to worklist");
promiseList.push(pr);
});
}
console.log("Transition *START*-" +promiseList.length +" ");
Promise.all(promiseList).catch(function(error) {
console.log("Part of TransitionCursor Failed!", error);
}).then(this.summarizeWorkDone());
在这两种情况下,输出都像
new Promise...
doing Exit stuff at time 0
new Promise...
doing Exit stuff at time 0
"Transition *START*-"
与预期
new Promise...
new Promise...
"Transition *START*-"
doing Exit stuff at time 0
doing Exit stuff at time 0
如何动态创建承诺列表以供稍后执行?
我对 promises 的理解确实不对,正如这个优秀页面上提到的:http://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html 首先它们会立即开始执行,其次要动态地执行,你必须使用工厂函数来延迟执行,如下所示:
首先创建链开始。
var chain = Promise.resolve();
// chain.then(this.doTranStart);
然后为每个状态(一个数组)创建一个代理闭包,以便可以使用适当的数据回调该函数。我不确定 javascript 中是否为此内置了一些东西,所以我从 actionscript 2.0 移植了一个库,当时它有类似的问题。
this.statesToExit.forEach(function (state) {
console.log("new Exit Promise Chain...");
var pxfn = GetProxy.getProxy(self, self.doExitFactory, [curTime,state._fn,state]);
chain = chain.then(pxfn);
});
然后 运行 工厂链,然后调用工厂然后执行承诺。
chain.catch(function(error) {
console.log("Part of TransitionCursor Failed!", error);
}).then(this.summarizeWorkDone);
首先是工厂方法,很简单
doExitFactory(curTime,fn,stateScope) {
console.log("doExitFactory " );//+ curTime,fn,stateScope );
return this.doExit(curTime,fn,stateScope);
}
这是完成这项工作的实际功能。在给定范围内动态调用函数。
doExit(curTime, _fn, stateScope) {
console.log("doExit");
return new Promise(function (resolve, reject) {
// console.log("doing actual Exit stuff at time ");//+ curTime);
_fn.apply(stateScope, [{sig: STATE.EXIT}, resolve, reject]);
resolve();
})
}
输出看起来像
TransitionCursor.setRoute
starting to create chain
new Exit Promise Chain...
new Exit Promise Chain...
finishing create chain
calling chain to start............
Transition *START*--------------------------
doExitFactory
doExit
IS_s11 (EXIT)
doExitFactory
doExit
IS_s1 (EXIT)
summarizeWorkDone:---------------
其中 IS_s11 和 IS_s1 是我想要按顺序 运行 的实际异步函数。
您写道:
new Promise((r)=>r()).then(new Promise((r)=>r());
您想写什么:
new Promise((r)=>r()).then(()=>new Promise((r)=>r()));
要使您的代码按您希望的方式运行,请更改
lastPr.then(pr);
到
lastPr.then(()=>pr);
好的,
所以人们对我的回答投了反对票,因为我提供了外部 link,它实际上是我写的。好难过!所以修改答案和之前的答案放在这个答案的底部。
在这里,我将重点关注第一个示例中的问题,因为这是我在 post.post.
底部的 link 中解释的内容
首先:您不是在链接承诺,而是在创建多个承诺。当你创建一个承诺时,你传递给构造函数的函数会立即被调用。查看下面 link 中教程的第 1 部分以了解详细信息。这就是为什么在 'new promise' 行之后得到输出行 'doing Exit stuff at time ...' 的原因。您没有说任何关于 curTime 的内容,但似乎这些值不正确,尽管这不是本文的重点 post。
其次, 您应该将 lastPr.then() 分配给 lastPr() 但您正在将新创建的 pr 分配给 lastPr。这在下面 link 的第 2 节中进行了解释。
第三, 我会说你的预期输出说我应该提醒你传递给 promise 构造函数的函数立即启动。所以你不应该在承诺创建期间打印任何东西,而是在 then() 方法中将它们下推。但是,我在这里没有这样做,所以您会看到第一行 'doing Exit stuff at time 0' 紧接在第一行 'new Promise...' 之后。
第四,你没有在预期的输出中显示'lastPr.then.'
注意:我更改了代码的 curTime 和 statesToExit(删除了 'this' 引用并分配了测试数组)
我建议这样:
var curTime = 0;
var lastPr = null;
console.log(" exit setup......................");
var statesToExit = [1, 2, 3]; // NOTE: the change to make this code runnable.
while (statesToExit.length > 0) {
var v = statesToExit.shift();
console.log("new Promise...");
if (lastPr == null) {
lastPr = new Promise(function (resolve, reject) {
console.log("doing Exit stuff at time " + curTime);
resolve(); //SOMETHING MORE SUBSTANTIAL GOES HERE
});
}
else {
console.log("lastPr.then."); // NOTE: This does not appear in your expected output
lastPr = lastPr.then(result => {
console.log("doing Exit stuff at time " + curTime);
return Promise.resolve(); //SOMETHING MORE SUBSTANTIAL GOES HERE
});
}
// console.log("adding pr to worklist");
// promiseList.push(pr);
// });
}
// NOTE: now you need to esecute the chain:
// you should handle promise rejection:
// check the tutorial link:
// https://github.com/tuhinpaul/syp-model/wiki/Programmatic-Chaining-and-Recursive-Functions-with-JavaScript-Promise
lastPr.catch(err => { console.log(err); });
以上代码的输出:
exit setup......................
new Promise...
doing Exit stuff at time 0
new Promise...
lastPr.then.
new Promise...
lastPr.then.
doing Exit stuff at time 0
doing Exit stuff at time 0
我在以下教程中描述了动态承诺链接:查看以下教程以获取
- javascript/node.js promises 和
的程序化(动态)链接
- 使用递归函数的 Promise 链接
Programmatic-Chaining-and-Recursive-Functions-with-JavaScript-Promise
我正在尝试动态链接承诺,以便处理需要按顺序发生的未知数量的异步调用。我正在使用原生支持 Promise 的 IO.JS/chrome。
promise 的创建会立即触发(至少相对于控制台输出而言)。我期待能够收集承诺然后传递给 Promise.all,但到那时他们已经因为我不明白的原因被解雇了。
下面是一种链接方法,由
var lastPr = null;
console.log(" exit setup......................");
while(this.statesToExit.length > 0) {
var v = this.statesToExit.shift();
console.log("new Promise...");
var pr = new Promise(function (resolve, reject) {
console.log("doing Exit stuff at time " +curTime);
resolve(); //SOMETHING MORE SUBSTANTIAL GOES HERE
});
console.log("lastPr.then.");
if (lastPr != null) {
lastPr.then(pr);
}
lastPr = pr;
// console.log("adding pr to worklist");
// promiseList.push(pr);
// });
}
另一种方法是
var promiseList= [];
console.log(" exit setup......................");
while(this.statesToExit.length > 0) {
var v = this.statesToExit.shift();
console.log("new Promise...");
var pr = new Promise(function (resolve, reject) {
console.log("doing Exit stuff at time " +curTime);
resolve(); //SOMETHING MORE SUBSTANTIAL GOES HERE
});
console.log("adding pr to worklist");
promiseList.push(pr);
});
}
console.log("Transition *START*-" +promiseList.length +" ");
Promise.all(promiseList).catch(function(error) {
console.log("Part of TransitionCursor Failed!", error);
}).then(this.summarizeWorkDone());
在这两种情况下,输出都像
new Promise...
doing Exit stuff at time 0
new Promise...
doing Exit stuff at time 0
"Transition *START*-"
与预期
new Promise...
new Promise...
"Transition *START*-"
doing Exit stuff at time 0
doing Exit stuff at time 0
如何动态创建承诺列表以供稍后执行?
我对 promises 的理解确实不对,正如这个优秀页面上提到的:http://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html 首先它们会立即开始执行,其次要动态地执行,你必须使用工厂函数来延迟执行,如下所示:
首先创建链开始。
var chain = Promise.resolve();
// chain.then(this.doTranStart);
然后为每个状态(一个数组)创建一个代理闭包,以便可以使用适当的数据回调该函数。我不确定 javascript 中是否为此内置了一些东西,所以我从 actionscript 2.0 移植了一个库,当时它有类似的问题。
this.statesToExit.forEach(function (state) {
console.log("new Exit Promise Chain...");
var pxfn = GetProxy.getProxy(self, self.doExitFactory, [curTime,state._fn,state]);
chain = chain.then(pxfn);
});
然后 运行 工厂链,然后调用工厂然后执行承诺。
chain.catch(function(error) {
console.log("Part of TransitionCursor Failed!", error);
}).then(this.summarizeWorkDone);
首先是工厂方法,很简单
doExitFactory(curTime,fn,stateScope) {
console.log("doExitFactory " );//+ curTime,fn,stateScope );
return this.doExit(curTime,fn,stateScope);
}
这是完成这项工作的实际功能。在给定范围内动态调用函数。
doExit(curTime, _fn, stateScope) {
console.log("doExit");
return new Promise(function (resolve, reject) {
// console.log("doing actual Exit stuff at time ");//+ curTime);
_fn.apply(stateScope, [{sig: STATE.EXIT}, resolve, reject]);
resolve();
})
}
输出看起来像
TransitionCursor.setRoute
starting to create chain
new Exit Promise Chain...
new Exit Promise Chain...
finishing create chain
calling chain to start............
Transition *START*--------------------------
doExitFactory
doExit
IS_s11 (EXIT)
doExitFactory
doExit
IS_s1 (EXIT)
summarizeWorkDone:---------------
其中 IS_s11 和 IS_s1 是我想要按顺序 运行 的实际异步函数。
您写道:
new Promise((r)=>r()).then(new Promise((r)=>r());
您想写什么:
new Promise((r)=>r()).then(()=>new Promise((r)=>r()));
要使您的代码按您希望的方式运行,请更改
lastPr.then(pr);
到
lastPr.then(()=>pr);
好的,
所以人们对我的回答投了反对票,因为我提供了外部 link,它实际上是我写的。好难过!所以修改答案和之前的答案放在这个答案的底部。
在这里,我将重点关注第一个示例中的问题,因为这是我在 post.post.
底部的 link 中解释的内容首先:您不是在链接承诺,而是在创建多个承诺。当你创建一个承诺时,你传递给构造函数的函数会立即被调用。查看下面 link 中教程的第 1 部分以了解详细信息。这就是为什么在 'new promise' 行之后得到输出行 'doing Exit stuff at time ...' 的原因。您没有说任何关于 curTime 的内容,但似乎这些值不正确,尽管这不是本文的重点 post。
其次, 您应该将 lastPr.then() 分配给 lastPr() 但您正在将新创建的 pr 分配给 lastPr。这在下面 link 的第 2 节中进行了解释。
第三, 我会说你的预期输出说我应该提醒你传递给 promise 构造函数的函数立即启动。所以你不应该在承诺创建期间打印任何东西,而是在 then() 方法中将它们下推。但是,我在这里没有这样做,所以您会看到第一行 'doing Exit stuff at time 0' 紧接在第一行 'new Promise...' 之后。
第四,你没有在预期的输出中显示'lastPr.then.'
注意:我更改了代码的 curTime 和 statesToExit(删除了 'this' 引用并分配了测试数组)
我建议这样:
var curTime = 0;
var lastPr = null;
console.log(" exit setup......................");
var statesToExit = [1, 2, 3]; // NOTE: the change to make this code runnable.
while (statesToExit.length > 0) {
var v = statesToExit.shift();
console.log("new Promise...");
if (lastPr == null) {
lastPr = new Promise(function (resolve, reject) {
console.log("doing Exit stuff at time " + curTime);
resolve(); //SOMETHING MORE SUBSTANTIAL GOES HERE
});
}
else {
console.log("lastPr.then."); // NOTE: This does not appear in your expected output
lastPr = lastPr.then(result => {
console.log("doing Exit stuff at time " + curTime);
return Promise.resolve(); //SOMETHING MORE SUBSTANTIAL GOES HERE
});
}
// console.log("adding pr to worklist");
// promiseList.push(pr);
// });
}
// NOTE: now you need to esecute the chain:
// you should handle promise rejection:
// check the tutorial link:
// https://github.com/tuhinpaul/syp-model/wiki/Programmatic-Chaining-and-Recursive-Functions-with-JavaScript-Promise
lastPr.catch(err => { console.log(err); });
以上代码的输出:
exit setup......................
new Promise...
doing Exit stuff at time 0
new Promise...
lastPr.then.
new Promise...
lastPr.then.
doing Exit stuff at time 0
doing Exit stuff at time 0
我在以下教程中描述了动态承诺链接:查看以下教程以获取
- javascript/node.js promises 和 的程序化(动态)链接
- 使用递归函数的 Promise 链接
Programmatic-Chaining-and-Recursive-Functions-with-JavaScript-Promise