以后如何访问承诺结果?

How do I access promise result later on?

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. 使用 youtube 模块下载关于在 YouTube 上托管的 screencast 的信息。
  2. 在数据库中存储有关 screencast 的信息。

这两个步骤自然是异步的。

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

我找到了 ,但是作为一个对 JS 相对缺乏经验的人,我不知道如何在这里应用那个答案。

嗯,有两种方法:

  1. 创建一个全局变量 screencast(就像您已经有一个 screencastId),它在所有 .then 调用之间共享
  2. 如果由于某种原因你不能在那里使用全局变量,你也可以在每个 .then 语句中 return 一个 new Promise 其中在 resolve 函数中你传递一个参数screencast

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

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)
})

在我看来,您可以拥有一个 glovar 变量 globalScreencast,并在第一步中执行类似的操作:

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

因此在第二步中您可以访问变量