在Javascript中使用协同程序的同步控制流程

时间:2014-02-03 04:38:45

标签: javascript coroutine

我想知道我们是否可以实现一个可以在Javascript中阻止的函数。例如:

var username = getUserName(); //wait for user input username in a certain way
doSth(username);

我希望getUserName可以阻止,直到用户输入有效的用户名。我想知道我们是否可以使用协程或其他方法来实现这一目标。谢谢。

4 个答案:

答案 0 :(得分:1)

在浏览器中,你最接近协程的是Ecmascript 6标准中提出的类似Python的generators。但是,到目前为止,只有Firefox和最新版本的NodeJ本身支持它们。

鉴于大多数浏览器不支持协同程序(并且由于旧版本的IE而不会长时间使用),您最好的选择是使用纯Javascript控制流库(见“async.js”或promises)或者使用一些工具来编译用协同程序扩展的Javascript方言回到continuation-passing-style。有一些使用ES6语法,另一些使用不同的语法(还有一些非JS语言编译为Javascript)

最后,为了保持完整,在Nodejs中有一个Fibers功能,它有点类似于协同程序,但它只是服务器端,因此我不认为它们对你非常有用。

答案 1 :(得分:0)

这不是“阻止”,但你总是可以使用回调

function getUsername(done) {
  try {
    var username = // some process that gets the username;
    return done(null, username);
  }
  catch (err) {
    return done(err);
  }
}

getUsername(function(err, username) {
  if (err) throw err;
  console.log(username);
}

答案 2 :(得分:0)

随着生成器到达javascript并且Aryn的帮助可以在Node.js或客户端使用协同程序和CSP(通信顺序进程)。

Node.js中的Aryn + Promise示例:

function getUsername(id) {
    return new Promise(function(resolve, reject) {
        db.query('select username from user where id = ?', [id], function(r){
            resolve(r[0].username)
        })
    })
}

// your coroutine
aryn.run(function*(){
    var username = yield getUsername(id)
    console.log(username)
})

使用Aryns drive功能:

db = aryn.drive(require('db'))

var getUsername = aryn.def(function*(){
    return yield aryn.receive(db.query('select username from user where id = ?', [id]))
})

aryn.run(function*(){
    var username = yield getUsername(id)
    console.log(username)
})

答案 3 :(得分:0)

这里是CSP风扇。我花了半年的时间在JavaScript解决方案中从事CSP的工作,我认为自己对此有所了解。如果您有兴趣,请检查Riew