Javascript承诺中的动态链接
如何在Javascript Promises中执行动态链接,我一直只看到调用的硬编码,例如,Javascript承诺中的动态链接,javascript,promise,Javascript,Promise,如何在Javascript Promises中执行动态链接,我一直只看到调用的硬编码,例如,(promise).then(request/functionName).then(request/functionName)自从Promises展开以来,只需继续添加然后语句,它将继续链接在一起 function asyncSeries(fns) { return fns.reduce(function(p, fn) { return p.then(fn); }, Promise.res
(promise).then(request/functionName).then(request/functionName)
自从Promises展开以来,只需继续添加然后语句,它将继续链接在一起
function asyncSeries(fns) {
return fns.reduce(function(p, fn) {
return p.then(fn);
}, Promise.resolve());
}
递归也是一种非常酷的方法:)
一种选择是利用对象的属性以及通过字符串调用它们的能力
我写了一个小样本,贴在下面
其思想是,您拥有希望在某个命名空间或对象中运行的函数集,就像我在“myNamespace”中所做的那样:
myNamespace = {
"A": function() {return "A Function";},
"B": function() {return "B Function";},
"C": function() {return "C Function";}
}
然后,您的主要承诺将运行,并且以某种方式(通过输入、ajax、提示等)您将获得要运行的函数的字符串值,直到运行时才知道:
My main promise使用提示从用户处获取信函:
var answer = prompt('Starting. Please pick a letter: A,B,C');
if(myNamespace[answer] === undefined)
{
alert("Invalid choice!");
reject("Invalid choice of: " + answer);
}
else
{
resolve(answer);
}
在下一个“then”中,我使用该值(通过resolve函数传递)调用函数:
.then(function(response) {
funcToRun = myNamespace[response]();})
最后,我将动态函数调用的结果输出到html,并使用一些递归的乐趣使其更具交互性,并证明它是动态的:
.then(function(){
document.getElementById('result').innerHTML = funcToRun;})
.then(function(){
if(prompt("Run Again? (YES/NO)")==="YES")
{
doWork();
}
});
myNamespace={
“A”:function(){return“A function”;},
“B”:函数(){返回“B函数”;},
“C”:函数(){返回“C函数”;}
}
函数doWork()
{
var函子;
新承诺(功能(解决、拒绝){
var answer=prompt('开始。请选择一个字母:a、B、C');
if(myNamespace[answer]==未定义)
{
警告(“无效选择!”);
拒绝(“无效选择:“+答案”);
}
其他的
{
决心(回答);
}
})
.然后(功能(响应){
funcToRun=myNamespace[response]();})
.然后(函数(){
document.getElementById('result')。innerHTML=funcToRun;})
.然后(函数(){
如果(提示(“再次运行?(是/否)”)=“是”)
{
销钉();
}
});
}
销钉()代码>
给定所有返回承诺的数组函数,您可以使用reduce()
按顺序运行它们:
var myAsyncFuncs = [
function (val) {return Promise.resolve(val + 1);},
function (val) {return Promise.resolve(val + 2);},
function (val) {return Promise.resolve(val + 3);},
];
myAsyncFuncs.reduce(function (prev, curr) {
return prev.then(curr);
}, Promise.resolve(1))
.then(function (result) {
console.log('RESULT is ' + result); // prints "RESULT is 7"
});
上面的示例使用了promise库,但所有promise库都具有类似的功能
另外,创建承诺返回函数数组通常是使用map()
的好选择。例如:
myNewOrmModels.map(function (model) {
return model.save.bind(model);
}).reduce(function (prev, curr) {
return prev.then(curr);
}, Promise.resolve())
.then(function (result) {
console.log('DONE saving');
});
此解决方案基于EcmaScript 6()中引入的使用承诺,因此在使用前请参阅表浏览器的支持
代码
var f1 = function(){
for (var i = 0; i < 800000000; i++) {}
console.log('Function1 is done');
}
var f2 = function(){
for (var i = 0; i < 800000000; i++) {}
console.log('Function2 is done');
}
var f3 = function(){
for (var i = 0; i < 800000000; i++) {}
console.log('Function3 is done');
}
var f4 = function(){
for (var i = 0; i < 800000000; i++) {}
console.log('Function4 is done');
}
callbacks = function(){
// copy passed arguments
var callbacks = arguments;
// create array functions
var callbacks = Object.keys(callbacks).map(function(el){ return callbacks[el] });
var now = Date.now();
callbacks.reduce(function(previousPromise, currentFunc){
return previousPromise.then(
function(){
currentFunc();
var seconds = (Date.now() - now) / 1000;
console.log('Gone', seconds, 'seconds');
}
)
}, Promise.resolve());
}
callbacks(f1, f2, f3, f4);
注:
如果函数包含计时器(针对此问题),则不起作用
我还尝试了jQuery的$Callbacks、$.Ajax和$.When,但没有帮助。
我发现,唯一的决定是在
计时器,但如果已完成功能,则不可接受。)
测试环境
这是ES7方式
假设在一个数组中定义了多个承诺
var funcs = [
_ => new Promise(res => setTimeout(_ => res("1"), 1000)),
_ => new Promise(res => setTimeout(_ => res("2"), 1000))
}
你想这样打电话
chainPromises(funcs).then(result => console.log(result));
为此,您可以使用async
和wait
async function chainPromises(promises) {
for (let promise of promises) { // must be for (.. of ..)
await promise();
}
}
这将按顺序(逐个)执行给定的函数,而不是并行执行。参数Promise
是一个函数数组,返回Promise
Plunker:我的api提供程序遇到了一个问题,执行Promise.all()会导致并发数据库出现问题
我的情况是,我需要得到每一个承诺结果,以显示一些“一切正常”或“某些错误”警报
我不知道为什么。。这段代码在承诺解决问题时使用reduce,但我无法让我的范围工作(现在调查太迟了)
所以多亏了这篇文章,我才带着这个小混蛋来到这里。。它没有抛光,但很好用
$scope.recurse = function(promises, promisesLength, results) {
if (promisesLength === 1) {
return promises[0].then(function(data){
results.push(data);
return results;
});
}
return promises[promisesLength-1].then(function(data) {
results.push(data);
return $scope.recurse(promises, promisesLength - 1, results);
});
}
然后我像这样调用函数:
var recurseFunction = $scope.recurse(promises, promises.length, results);
recurseFunction.then(function (response) { ... });
我希望它能有所帮助。查看以下教程以了解更多信息
javascript/node.js承诺的编程(动态)链接和
使用递归函数的承诺链
我认为最简单的方法是:
const executePromises = function(listOfProviders){
const p = Promise.resolve(null);
for(let i = 0; i < listOfProviders.length; i++){
p = p.then(v => listOfProviders[i]());
}
return p;
};
const executePromises=函数(listOfProviders){
const p=Promise.resolve(null);
for(设i=0;ilistOfProviders[i]());
}
返回p;
};
我相信以上基本上等同于:
const executePromises = async function(listOfProviders) {
for(let i = 0; i < listOfProviders.length; i++){
await listOfProviders[i]();
}
};
const executePromises=异步函数(listOfProviders){
for(设i=0;i
Dynamic-它们来自哪里?你想解决的问题是什么?当然,您可以传递任何您喜欢的回调,无论选择何种方式,而不仅仅是硬编码的函数表达式。感谢Bergi的回复,它们来自用户操作/事件,如按钮单击等,您的意思是像var promise=…;button.onclick=函数(e){promise.then(doSomething);}代码>?你当然能做到,是的。你试过了吗?是的,用同样的方法…我没有主意了Bergi…那么你想要得到什么结果呢?您是否已经有了不起作用或看起来太复杂的代码?谢谢Jason。。。我将尝试实现相同的功能,并让您知道Hi Jason…快速问题…我将从用户操作中收到许多请求(要调用的FN),我如何检查当前承诺状态,然后链接它是否仍处于挂起状态,或者如果状态为resolved@RamuAjay因此,有一个承诺状态值,但它是私有的。我的猜测是使用.done(function(){isPromiseDone=true;})
或某个外部变量来保存当前承诺状态。至于添加额外的“thens”,您可以保留一个函数数组,在.done()
函数中,您可以检查该数组并在promise中添加更多的“thens”。。。不过这只是一个猜测。嗨,特拉维斯……快速提问……我将收到来自用户操作的许多请求(要调用的FN),呵呵
$scope.recurse = function(promises, promisesLength, results) {
if (promisesLength === 1) {
return promises[0].then(function(data){
results.push(data);
return results;
});
}
return promises[promisesLength-1].then(function(data) {
results.push(data);
return $scope.recurse(promises, promisesLength - 1, results);
});
}
var recurseFunction = $scope.recurse(promises, promises.length, results);
recurseFunction.then(function (response) { ... });
const executePromises = function(listOfProviders){
const p = Promise.resolve(null);
for(let i = 0; i < listOfProviders.length; i++){
p = p.then(v => listOfProviders[i]());
}
return p;
};
const executePromises = async function(listOfProviders) {
for(let i = 0; i < listOfProviders.length; i++){
await listOfProviders[i]();
}
};