Javascript 使用fs.writeFileSync时避免争用条件
我正在使用bluebird、request promise和writeFileSync下载png并将其写入文件,我的代码是:`Javascript 使用fs.writeFileSync时避免争用条件,javascript,node.js,Javascript,Node.js,我正在使用bluebird、request promise和writeFileSync下载png并将其写入文件,我的代码是:` function downloadPng(url) { return new Promise(function (resolve, reject) { return request.get({ url : url, headers : header, encoding: 'b
function downloadPng(url) {
return new Promise(function (resolve, reject) {
return request.get({
url : url,
headers : header,
encoding: 'binary',
}).then((res) => {
fs.writeFileSync('fileName', res, 'binary')
return foo('fileName')//my function using fileName
}).then((resultFromFoo) => {
resolve(resultFromFoo)
}).catch((error) => {
reject(error)
})
我认为使用writeFileSync可以确保只有在writeFileSync成功后才会执行foo?但是我仍然得到一个竞争条件,在创建文件之前调用了我的foo,我如何正确地做到这一点?问题更可能出现在其他地方,显示的代码应该可以工作,只要不同时调用
downloadPng
除此之外,在此处创建新承诺没有意义,因为request.get
已经返回了一个承诺,而不是Sync
,您应该使用指定版本的write命令:
const Promise = require('bluebird')
const fs = Promise.promisifyAll(require('fs'))
function downloadPng(url) {
return request.get({
url: url,
headers: header,
encoding: 'binary',
}).then(res => {
return fs.writeFileAsync('fileName', res, 'binary')
})
.then(() => {
return foo('fileName') //my function using fileName
})
})
如果您可以使用wait
和async
,您可以这样编写:
const Promise = require('bluebird')
const fs = Promise.promisifyAll(require('fs'))
async function downloadPng(url) {
var res = await request.get({
url: url,
headers: header,
encoding: 'binary',
});
await fs.writeFileAsync('fileName', res, 'binary')
return foo('fileName')
})
为什么你要创造一个承诺,却从不要求解决或拒绝?这很奇怪。此代码应该可以工作,并且应该在调用
foo()
之前完成文件的编写。更可能的情况是问题出在其他地方,只要不同时调用downloadPng
,显示的代码应该可以工作。此外,在这里创建一个新的承诺是没有意义的,因为request.get
已经返回了一个承诺。