bluebird 如何知道继续执行此链中的下一个“then”?
How does bluebird know to proceed to the next `then` in this chain?
通过 promisified fs-extra,我知道我可以使用 then
访问文件。我 猜测 那里有某种机制,在它获得文件后它知道移动到 then
链中的下一个 link。但是,接下来 then
我只是放了一个简单的 for 循环。下一个只是向控制台打印一行。我希望返回某种 Promise 对象,以便它沿着链向下移动。沿着这条链向下推进需要什么?例如,如果我将 setTimeout 设置为一秒钟,那么链会继续并乱序打印。
var Promise = require('bluebird')
, fs = Promise.promisifyAll(require('fs-extra'))
fs.readdirAsync(dir)
.bind(this)
.then((files) => {
this.files = files;
})
.then(() => {
var num = 10000
this.files.forEach((file, index, array) => {
for(i = 0; i < num; i++){
console.log(num*i);
}
});
})
.then(() => {
console.log('middle of it');
})
.then(() => {
console.log('done with it');
})
.catch((err) => {
console.log(err);
});
每次调用 .then()
return 都是一个新的承诺,它有自己的 .then()
处理程序。该承诺会自动链接到先前的承诺,因此当先前的承诺完全用它自己的 .then()
处理程序完成并且 .then()
处理程序没有 return 承诺时承诺它 returned 已解决,然后它可以触发链中的下一个承诺被解决,导致它为它的 .then()
处理程序重复循环。
关键是 p.then()
return 是一个新的 promise,当 p.then()
完成时它本身就被解决了,因此它可以触发链中的下一步 p.then().then()
等等。
请记住,.then()
处理程序可以执行以下四种操作之一:
- Return 无(与 returning
undefined
相同)。
- Return一个值
- Return一个承诺
- 抛出异常
对于前两个(returning 值),这仅表示 .then()
处理程序已完成,现在可以触发链中的下一个处理程序。
当 return 承诺时,该承诺本身与 .then()
处理程序挂钩,因此可以对其进行监视。 If/when 它解决了,链继续。 If/when it rejects,链被拒绝。 returned 的 promise 可能已经被解决或拒绝,或者可能在未来被解决或拒绝,在行为上没有有意义的差异。如果 returned promise 从未被解决或拒绝,则 promise 链将停止并且不会继续,直到它被解决或拒绝(与任何承诺相同)。
如果 .then()
处理程序抛出异常,这会被 .then()
包装器捕获,并自动转换为拒绝承诺,并将异常作为拒绝原因。
For example, if I put in a setTimeout for a second, then chain
continues and prints out of order.
您不能非常有效地单独使用 setTimeout()
来延迟承诺链。相反,您需要 return 来自 .then()
处理程序的承诺,该承诺在一段时间后得到解决。 Bluebird .delay(x)
可以为您做到这一点。
或者,如果不使用 Bluebird,您可以自己编写一个代码:
function delay(t) {
return new Promise(function(resolve) {
setTimeout(resolve, t);
});
}
fn().then(function() {
// delay promise chain by 1000ms
return delay(1000);
}).then(function() {
// promise chain continues here
});
或者,使用 Bluebird 承诺,它就像:
fn().delay(1000).then(function() {
delayed promise chain continues here
});
通过 promisified fs-extra,我知道我可以使用 then
访问文件。我 猜测 那里有某种机制,在它获得文件后它知道移动到 then
链中的下一个 link。但是,接下来 then
我只是放了一个简单的 for 循环。下一个只是向控制台打印一行。我希望返回某种 Promise 对象,以便它沿着链向下移动。沿着这条链向下推进需要什么?例如,如果我将 setTimeout 设置为一秒钟,那么链会继续并乱序打印。
var Promise = require('bluebird')
, fs = Promise.promisifyAll(require('fs-extra'))
fs.readdirAsync(dir)
.bind(this)
.then((files) => {
this.files = files;
})
.then(() => {
var num = 10000
this.files.forEach((file, index, array) => {
for(i = 0; i < num; i++){
console.log(num*i);
}
});
})
.then(() => {
console.log('middle of it');
})
.then(() => {
console.log('done with it');
})
.catch((err) => {
console.log(err);
});
每次调用 .then()
return 都是一个新的承诺,它有自己的 .then()
处理程序。该承诺会自动链接到先前的承诺,因此当先前的承诺完全用它自己的 .then()
处理程序完成并且 .then()
处理程序没有 return 承诺时承诺它 returned 已解决,然后它可以触发链中的下一个承诺被解决,导致它为它的 .then()
处理程序重复循环。
关键是 p.then()
return 是一个新的 promise,当 p.then()
完成时它本身就被解决了,因此它可以触发链中的下一步 p.then().then()
等等。
请记住,.then()
处理程序可以执行以下四种操作之一:
- Return 无(与 returning
undefined
相同)。 - Return一个值
- Return一个承诺
- 抛出异常
对于前两个(returning 值),这仅表示 .then()
处理程序已完成,现在可以触发链中的下一个处理程序。
当 return 承诺时,该承诺本身与 .then()
处理程序挂钩,因此可以对其进行监视。 If/when 它解决了,链继续。 If/when it rejects,链被拒绝。 returned 的 promise 可能已经被解决或拒绝,或者可能在未来被解决或拒绝,在行为上没有有意义的差异。如果 returned promise 从未被解决或拒绝,则 promise 链将停止并且不会继续,直到它被解决或拒绝(与任何承诺相同)。
如果 .then()
处理程序抛出异常,这会被 .then()
包装器捕获,并自动转换为拒绝承诺,并将异常作为拒绝原因。
For example, if I put in a setTimeout for a second, then chain continues and prints out of order.
您不能非常有效地单独使用 setTimeout()
来延迟承诺链。相反,您需要 return 来自 .then()
处理程序的承诺,该承诺在一段时间后得到解决。 Bluebird .delay(x)
可以为您做到这一点。
或者,如果不使用 Bluebird,您可以自己编写一个代码:
function delay(t) {
return new Promise(function(resolve) {
setTimeout(resolve, t);
});
}
fn().then(function() {
// delay promise chain by 1000ms
return delay(1000);
}).then(function() {
// promise chain continues here
});
或者,使用 Bluebird 承诺,它就像:
fn().delay(1000).then(function() {
delayed promise chain continues here
});