2015-09-12 159 views
0

我试图动态链接承诺,以处理需要按顺序发生的未知数量的异步调用。我使用支持Promise的IO.JS/chrome。javascript ES6动态链接承诺

承诺的创建立即触发(至少相对于控制台输出)。我期待能够收集承诺,然后传递给Promise.all,但那时他们已经因为我不明白的原因而被解雇了。

这里有那么链接的一种方法,通过一个评论对Dynamic Chaining in Javascript Promises

  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*-" 

VS预计的

new Promise... 
new Promise... 
    "Transition *START*-" 
doing Exit stuff at time 0 
doing Exit stuff at time 0 

我该如何动态创建一个承诺列表以便稍后执行?

+0

它为什么无论什么时候到底是执行承诺的身体吗?承诺不保证他们的身体稍后会被执行。 – zerkms

+0

也许承诺不是你在这里需要的东西,看起来像执行顺序很重要,所以你想建立某种按摩队列,然后让它执行..但在你的例子中,如果只有一个项目statesToExit ? – webdeb

+0

你对承诺做什么以及如何使用它们的理解看起来相当遥远。我们可以帮助您重新构建,但需要了解是否希望所有异步操作以串行(一个接一个)或并行(全部同时开始)运行?我们还需要查看您的实际异步操作。现在你的问题中的代码完全是同步的,因此不需要承诺。 – jfriend00

回答

-1

我承诺的理解确实关闭,这个优秀的网页上提到: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是实际异步功能,我想才能运行。

-1

您写道:

new Promise((r)=>r()).then(new Promise((r)=>r()); 

你想写什么:

new Promise((r)=>r()).then(()=>new Promise((r)=>r())); 

为了使您的代码工作,你所希望的方式,改变

lastPr.then(pr); 

lastPr.then(()=>pr); 
-1

好吧,

所以人们投我的答案,因为我提供的外部链接,其实是我写的。好难过!所以修改答案和以前的答案在这个答案的底部。

在这里,我将重点介绍第一个例子中的问题,因为这是我在本文底部的链接中解释的。

首先:你没有链接承诺,但创造了多重承诺。在创建承诺时,您传递给构造函数的函数会立即被调用。有关详细信息,请参阅下面链接中的教程的第1部分。这就是为什么你在'新承诺'行后得到输出行“在......时间内完成退出事务......”的原因。你没有说curTime的任何内容,但似乎这些值并不正确,尽管这不是本文的重点。

其次,您应该将lastPr.then()分配给lastPr(),但您将新创建的pr分配给lastPr。以下链接的第2部分对此进行了解释。

第三,我会说你的预期输出说我应该提醒你,传递给promise构造函数的函数立即启动。所以你不应该在创建promise的时候打印任何东西,而是在then()方法中将它们推下。然而,我在这里没有这样做,所以你会看到第一个'在时间0行做退出的东西'行出现在第一个'新的承诺...'行之后。

第四,你没有显示'lastPr.then'。在预期输出

注:我改变你的代码的CURTIME和statesToExit(删除“这个”参考和指定的测试阵列)

我建议是这样的:

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 

我在下面的教程中描述了动态承诺链接:检查以下内容教程

  1. javascript/node的编程(动态)链接。JS承诺和
  2. 无极链接使用递归函数

Programmatic-Chaining-and-Recursive-Functions-with-JavaScript-Promise

+0

指向外部教程并不是一个合适的答案 - 这就是人们投票的原因。你应该在答案的正文中回答这个问题。 –

+0

谢谢@Mark_M通知。在这里获得投票是令人失望的,因为我已经在我的链接中明确地解决了这个页面的问题。我只是不想在这里重复同样的答案。但是,我会添加到我的答案。 –

+1

现在检查,老兄! –