我如何在以后访问承诺结果?

时间:2015-05-06 09:41:31

标签: javascript promise bluebird

var screencastId = 'abc'

var a = youtube.get(screencastId);
a.then(function(screencast) {
  // Yay. I have the screencast information here.
  console.log(screencast);
});

// How do I access the `screencast` variable down here?
connection.beginTransactionAsync().then(function() {
  return connection.queryAsync('INSERT IGNORE INTO Channels SET ?', screencast.channel);
}).then(function() {
  return connection.queryAsync('INSERT INTO Screencasts SET ?', screencast);
}).then(function() {
  var values = tags.map(function(tag) { return [tag]; });
  return connection.queryAsync('INSERT IGNORE INTO Tags VALUES ?', [values])
}).then(function() {
  var values = tags.map(function(tag) { return [screencast.screencastId, tag]; });
  return connection.queryAsync('INSERT INTO ScreencastTags VALUES ?', [values])
}).then(function() {
  return connection.commit();
}).error(function(e) {
  connection.rollback();
  winston.error(e);
});

此代码可分为两个不同的步骤:

  1. 使用screencast模块下载有关YouTube托管的youtube的信息。
  2. 将有关screencast的信息存储在数据库中。
  3. 这两个步骤当然都是异步的。

    我的问题是,如何在第二步中访问screencast参数?

    我找到了this comprehensive answer,但作为一个相对缺乏JS经验的人,我无法解决如何在这里应用这个答案。

2 个答案:

答案 0 :(得分:1)

嗯,有两种方法:

  1. 创建一个全局变量screencast(就像您已经拥有screencastId),该变量在所有.then次来电之间共享
  2. 如果出于某种原因你不能使用全局变量,你也可以在每个.then语句中返回new Promise resolve函数中传递参数screencast < / LI>

    所以这是我看到它的第一种方式(但遗憾的是无法测试):

    var screencastId = 'abc', screencast
    
    youtube.get(screencastId)
    .then(function(sc) {
      screencast = sc;
    })
    
    // you need this to keep the chain
    .then(function(){
      return connection.beginTransactionAsync()
    })
    
    .then(function() {
      return connection.queryAsync('INSERT IGNORE INTO Channels SET ?', screencast.channel);
    }).then(function() {
      return connection.queryAsync('INSERT INTO Screencasts SET ?', screencast);
    }).then(function() {
      var values = tags.map(function(tag) { return [tag]; });
      return connection.queryAsync('INSERT IGNORE INTO Tags VALUES ?', [values])
    }).then(function() {
      var values = tags.map(function(tag) { return [screencast.screencastId, tag]; });
      return connection.queryAsync('INSERT INTO ScreencastTags VALUES ?', [values])
    }).then(function() {
      return connection.commit();
    }).error(function(e) {
      connection.rollback();
      winston.error(e);
    });
    

    返回新的Promise示例

    youtube.get(screencastId)
    .then(function(sc) {
      return new Promise(function(resolve,reject){
        resolve(sc)
      })
    })
    .then(function(sc){
      console.log(sc)
    })
    

答案 1 :(得分:1)

在我看来,你可以有一个glovar变量globalScreencast,并在你的第一步做类似的事情:

a.then(function(screencast) {
    // Yay. I have the screencast information here.
    console.log(screencast);
    globalScreencast = screencast;
});

然后在第二步中,您可以访问变量