我正在开发一个Node.js项目,我在使用Promise
函数包装setTimeout
函数时遇到问题。
我原来的Promise
功能:
我想在调用setTimeout()
时包装此函数,但在传递Promise
对象时遇到问题。我需要Promise
对象和setTimeout()
函数中可用的数据对象,但当我将它们作为参数传递给setTimeout()
时,我仍然会收到以下错误:
TypeError:无法读取属性'然后'未定义的
我的代码:
return Promise.props(data).then(function (data) {
data.companies = data.order && data.order.companies;
if (!data.companies) {
data.companies = {};
data.companies[data.company.id] = data.company;
}
if (data.order) {
if (data.order.contactentry) {
data.order.pointofcontact = data.order.contactentry + ' ' + phone(data.order.contactentryphone);
} else if (data.order.borrowername) {
data.order.pointofcontact = data.order.borrowername + ' ' + phone(data.order.borrowerphone);
} else if (data.order.lockboxcode) {
data.order.pointofcontact = 'Lockbox ' + data.order.lockboxcode
}
}
if (data.part && data.order && data.part.vendor) {
var oid = data.order && data.order.id;
var vid = data.part && data.part.vendor && data.part.vendor.id;
if (!oid || !vid) {
var e = new Error('Could not assemble vendor accept url, order id or part vendor id are missing')
log.error({
error: e,
data,
}, e.message);
throw e;
}
}
return data;
});
当作为参数传入时,数据对象在函数内部可用,但Promise
对象不可用。
如何正确传递Promise
对象以使其在setTimeout()
内可用?
答案 0 :(得分:3)
你正在从内到外接近这个。如果要将非承诺异步代码(例如setTimeout
)合并到基于承诺的代码中,则应该隔离包装的非承诺部分,而不是将其与其余的承诺代码混合得太深。
setTimeout
的承诺包装:
function delay(ms) {
return new Promise(function (resolve) {
setTimeout(resolve, ms);
});
}
然后你可以使用它:
return Promise.props(data)
.then(function (result) {
return delay(1000).return(result);
});
由于您似乎在使用Bluebird,您还可以跳过所有setTimeout
内容并使用内置的.delay
方法:
return Promise.props(data).delay(1000);
请注意,上述任何一项都会将额外的 1秒延迟添加到解析data
中所有承诺所需的时间。如果您的目标只是让最短总时间为1秒,那么您可以使用this question中的方法:
return Promise.delay(1000).return(Promise.props(data));
答案 1 :(得分:0)
我会忘记使用setTimeout的参数/返回值,只使用new Promise
在调用Promise.props之前延迟:
return new Promise(function (resolve) {
window.setTimeout(function () {
resolve(Promise.props(data));
}, 1000);
});
或者,延迟Promise.props的结果:
return Promise.props(data).then(function (data) {
return new Promise(function (resolve) {
window.setTimeout(function () {
resolve(data);
}, 1000);
});
});
编辑:如果你正在使用Bluebird,看起来它们内置了延迟运算符: