如何在承诺之间等待

How to wait between promises

我有一个命令 returns 在履行之前,所以我想在遵循承诺链之前稍等片刻。有什么最佳做法吗?

 new Promise(function (resolve, reject) {
      exec('netbeast new test-app', function (err, stdout, stderr) {
        if (err) return reject(err)
        else return resolve(PATH_TO_APP)
      })
    })
    .then(fs.readdirAsync)
    .then(fs.readFileAsync.bind(fs, PATH_TO_APP + '/server.js'))
    .then(function (data) {
      var shebang = data.toString().slice(0, data.toString().indexOf('\n'))
      shebang.should.equal('#!/usr/bin/env node')
      return Promise.resolve()
    })
    .then(fs.readJsonAsync.bind(fs, PATH_TO_APP + '/package.json'))
    .then(function (data) {
      return fs.accessAsync(PATH_TO_APP + '/' + data.main, fs.X_OK)
    })
    .then(done)

它可能在某些用例中很有用,因为在开始另一个操作之前稍等片刻会很方便。我认为最简单的方法是:

.then(function() {
    return new Promise(function (resolve) {
         setTimeout(resolve, TIME_TO_WAIT_IN_ms)
    })
})

编辑: 我不认为有一个 "best practice" 可以做到这一点。如上所述,异步编程中没有考虑等待。但是我想它可以用于边缘情况,根据要求,需要解决方法。

编辑 2:如下所述,bluebird(一个 promise 库)为此内置了快捷方式。为了一个承诺 p.delay(TIME_IN_ms).then(...)p.then(() => return Promise.delay(TIME_IN_ms)).

Promise 只会在您调用 rejectresolve 后调用 then 中的代码。如果不是这样,那就有大问题了。

如果想延迟解决promise,可以延迟调用reject或resolve:

  exec('netbeast new test-app', function (err, stdout, stderr) {
    setTimeout( () => {
        if (err) reject(err);
        else resolve(PATH_TO_APP);
    }, 100);
  })

我删除了回调中的 return,因为我不明白为什么。

I have a command that returns before fulfilling

如果该操作与您可以监控并知道何时完成的承诺无关,这听起来像是一个设计错误。您应该修复您的操作,以便在异步操作实际完成之前它不会完成。您没有确切解释您的问题出在哪里,但如果您这样做了,我们可能会帮助您解决真正的问题,而不是拖延时间。

如果这是多个 promise 之间的协调问题,那么您可能只需要确保各种异步操作适当地链接在一起,以便等待前一个操作,或者通过 return .then() 处理程序,return 从允许调用者等待完成的函数承诺或适当地将操作与连续的 .then() 处理程序链接起来。


如果您确实需要插入延迟,看起来您正在使用包含内置延迟机制的 Bluebird。在给定的承诺 p 上,您可以使用 .delay(n) 方法:

p.delay(100).then(...)   // wait 100ms before allowing promise chain to proceed

或者,在 .then() 处理程序中,您可以 return Promise.delay(n) 如:

p.then(function(data) {
   ...
   return Promise.delay(100);  // wait 100ms before allowing promise chain to proceed
})